aboutsummaryrefslogtreecommitdiffstats
path: root/core/module-list.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/module-list.c')
-rw-r--r--core/module-list.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/core/module-list.c b/core/module-list.c
index 7bf05e1..b3a9ed3 100644
--- a/core/module-list.c
+++ b/core/module-list.c
@@ -1137,7 +1137,8 @@ unsigned pure_list_form(const PureList *list) { return list->form; }
const size_t pure_list_layout[] = {
[LIST_COUNT_AT] = offsetof(PureList, count), [LIST_MEMBERS_AT] = offsetof(PureList, members),
[LIST_MEMBER_CAPACITY_AT] = offsetof(PureList, member_capacity), [LIST_BITMAP_AT] = offsetof(PureList, bitmap),
- [LIST_FORM_AT] = offsetof(PureList, form), [LIST_COLUMNS_AT] = offsetof(PureList, columns)};
+ [LIST_FORM_AT] = offsetof(PureList, form), [LIST_COLUMNS_AT] = offsetof(PureList, columns),
+ [LIST_VERSION_AT] = offsetof(PureList, version)};
bool pure_list_lookup(const PureList *list, unsigned key_field, PureCell key, unsigned field, PureCell *cell) {
bool found;
@@ -1757,6 +1758,7 @@ static void open_array_run(const PureList *list, size_t at, PureRun *run) {
run->start = at;
run->count = list->form == DENSE ? 1 : (unsigned)(list->count - at < PURE_LIST_RUN ? list->count - at : PURE_LIST_RUN);
run->depth = 0;
+ run->pathless = false;
for (unsigned f = 0; f < l->fields; ++f)
if (pure_cell_text(l->kinds[f])) run->column[f].texts = (const PureSpan *)list->columns[f] + row;
else if (l->kinds[f] == PURE_CELL_INTEGER) run->column[f].integers = (const int64_t *)list->columns[f] + row;
@@ -1772,6 +1774,16 @@ bool pure_list_run(const PureList *list, size_t at, PureRun *run) {
return true;
}
}
+ size_t within;
+ const Node *kept = fingered(list, at, &within); /* a slice's first item, found by key just before */
+ if (kept) {
+ run->path[0] = kept;
+ run->depth = 0;
+ run->pathless = true; /* the run after it found from the root */
+ run->start = at - within;
+ open_run(&list->layout, kept, run);
+ return true;
+ }
const Node *node = list->root;
size_t start = 0;
unsigned depth = 0;
@@ -1785,6 +1797,7 @@ bool pure_list_run(const PureList *list, size_t at, PureRun *run) {
run->path[depth] = node;
run->depth = depth;
run->start = start;
+ run->pathless = false;
open_run(&list->layout, node, run);
return true;
}
@@ -1798,6 +1811,23 @@ bool pure_list_next(const PureList *list, PureRun *run) {
open_array_run(list, run->start + run->count, run);
return true;
}
+ if (run->pathless) { /* the next from the root, with its path */
+ size_t at = run->start + run->count;
+ if (at >= list->count) return false;
+ const Node *node = list->root;
+ size_t start = 0;
+ unsigned depth = 0;
+ while (!node->leaf) {
+ unsigned i = child_at(node, at - start);
+ start += guide(node)->before[i];
+ run->path[depth] = node;
+ run->taken[depth++] = (uint8_t)i;
+ node = child(node, i);
+ }
+ run->path[depth] = node, run->depth = depth, run->start = start, run->pathless = false;
+ open_run(&list->layout, node, run);
+ return true;
+ }
size_t start = run->start + run->count;
unsigned depth = run->depth;
while (depth && run->taken[depth - 1] + 1u >= ((const Node *)run->path[depth - 1])->count) --depth;