static void adjust_parent_sep(struct cursor *cursor, int level, __be64 newsep) { if(DEBUG_MODE_K==1) { printf("\t\t\t\t%25s[K] %25s %4d #in\n",__FILE__,__func__,__LINE__); } /* Update separating key until nearest common parent */ while (level >= 0) { struct path_level *parent_at = &cursor->path[level]; struct index_entry *parent = parent_at->next - 1; assert(0 < be64_to_cpu(parent->key)); assert(be64_to_cpu(parent->key) < be64_to_cpu(newsep)); log_bnode_adjust(cursor->btree->sb, bufindex(parent_at->buffer), be64_to_cpu(parent->key), be64_to_cpu(newsep)); parent->key = newsep; mark_buffer_unify_non(parent_at->buffer); if (parent != level_node(cursor, level)->entries) break; level--; } }
static void cursor_check(struct cursor *cursor) { if(DEBUG_MODE_K==1) { printf("\t\t\t\t%25s[K] %25s %4d #in\n",__FILE__,__func__,__LINE__); } if (cursor->level == -1) return; tuxkey_t key = 0; block_t block = cursor->btree->root.block; for (int i = 0; i <= cursor->level; i++) { assert(bufindex(cursor->path[i].buffer) == block); if (i == cursor->level) break; struct bnode *bnode = level_node(cursor, i); struct index_entry *entry = cursor->path[i].next - 1; assert(bnode->entries <= entry); assert(entry < bnode->entries + bcount(bnode)); /* * If this entry is most left, it should be same key * with parent. Otherwise, most left key may not be * correct as next key. */ if (bnode->entries == entry) assert(be64_to_cpu(entry->key) == key); else assert(be64_to_cpu(entry->key) > key); block = be64_to_cpu(entry->block); key = be64_to_cpu(entry->key); } }
static void remove_index(struct cursor *cursor, struct chopped_index_info *cii) { int level = cursor->level; struct bnode *node = level_node(cursor, level); struct chopped_index_info *ciil = &cii[level]; /* Collect chopped index in this node for logging later */ if (!ciil->count) ciil->start = be64_to_cpu((cursor->path[level].next - 1)->key); ciil->count++; /* Remove an index */ bnode_remove_index(node, cursor->path[level].next - 1, 1); --(cursor->path[level].next); mark_buffer_rollup_non(cursor->path[level].buffer); /* * Climb up to common parent and update separating key. * * What if index is now empty? (no deleted key) * * Then some key above is going to be deleted and used to set sep * Climb the cursor while at first entry, bail out at root find the * node with the old sep, set it to deleted key */ /* There is no separator for last entry or root node */ if (!level || cursor_level_finished(cursor)) return; /* If removed index was not first entry, no change to separator */ if (cursor->path[level].next != node->entries) return; adjust_parent_sep(cursor, level - 1, cursor->path[level].next->key); }
/* There is no next entry? */ static inline int level_finished(struct cursor *cursor, int level) { if(DEBUG_MODE_K==1) { printf("\t\t\t\t%25s[K] %25s %4d #in\n",__FILE__,__func__,__LINE__); } struct bnode *node = level_node(cursor, level); return cursor->path[level].next == node->entries + bcount(node); }
static void adjust_parent_sep(struct cursor *cursor, int level, __be64 newsep) { /* Update separating key until nearest common parent */ while (level >= 0) { struct path_level *parent_at = &cursor->path[level]; struct index_entry *parent = parent_at->next - 1; assert(0 < be64_to_cpu(parent->key)); assert(be64_to_cpu(parent->key) < be64_to_cpu(newsep)); log_bnode_adjust(cursor->btree->sb, bufindex(parent_at->buffer), be64_to_cpu(parent->key), be64_to_cpu(newsep)); parent->key = newsep; mark_buffer_rollup_non(parent_at->buffer); if (parent != level_node(cursor, level)->entries) break; level--; } }
/* There is no next entry? */ static inline int level_finished(struct cursor *cursor, int level) { struct bnode *node = level_node(cursor, level); return cursor->path[level].next == node->entries + bcount(node); }