diff options
Diffstat (limited to 'lib/assoc_array.c')
-rw-r--r-- | lib/assoc_array.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/lib/assoc_array.c b/lib/assoc_array.c index 155c55d8db5f..4e53be8bc590 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c | |||
@@ -598,21 +598,31 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit, | |||
598 | if ((edit->segment_cache[ASSOC_ARRAY_FAN_OUT] ^ base_seg) == 0) | 598 | if ((edit->segment_cache[ASSOC_ARRAY_FAN_OUT] ^ base_seg) == 0) |
599 | goto all_leaves_cluster_together; | 599 | goto all_leaves_cluster_together; |
600 | 600 | ||
601 | /* Otherwise we can just insert a new node ahead of the old | 601 | /* Otherwise all the old leaves cluster in the same slot, but |
602 | * one. | 602 | * the new leaf wants to go into a different slot - so we |
603 | * create a new node (n0) to hold the new leaf and a pointer to | ||
604 | * a new node (n1) holding all the old leaves. | ||
605 | * | ||
606 | * This can be done by falling through to the node splitting | ||
607 | * path. | ||
603 | */ | 608 | */ |
604 | goto present_leaves_cluster_but_not_new_leaf; | 609 | pr_devel("present leaves cluster but not new leaf\n"); |
605 | } | 610 | } |
606 | 611 | ||
607 | split_node: | 612 | split_node: |
608 | pr_devel("split node\n"); | 613 | pr_devel("split node\n"); |
609 | 614 | ||
610 | /* We need to split the current node; we know that the node doesn't | 615 | /* We need to split the current node. The node must contain anything |
611 | * simply contain a full set of leaves that cluster together (it | 616 | * from a single leaf (in the one leaf case, this leaf will cluster |
612 | * contains meta pointers and/or non-clustering leaves). | 617 | * with the new leaf) and the rest meta-pointers, to all leaves, some |
618 | * of which may cluster. | ||
619 | * | ||
620 | * It won't contain the case in which all the current leaves plus the | ||
621 | * new leaves want to cluster in the same slot. | ||
613 | * | 622 | * |
614 | * We need to expel at least two leaves out of a set consisting of the | 623 | * We need to expel at least two leaves out of a set consisting of the |
615 | * leaves in the node and the new leaf. | 624 | * leaves in the node and the new leaf. The current meta pointers can |
625 | * just be copied as they shouldn't cluster with any of the leaves. | ||
616 | * | 626 | * |
617 | * We need a new node (n0) to replace the current one and a new node to | 627 | * We need a new node (n0) to replace the current one and a new node to |
618 | * take the expelled nodes (n1). | 628 | * take the expelled nodes (n1). |
@@ -717,33 +727,6 @@ found_slot_for_multiple_occupancy: | |||
717 | pr_devel("<--%s() = ok [split node]\n", __func__); | 727 | pr_devel("<--%s() = ok [split node]\n", __func__); |
718 | return true; | 728 | return true; |
719 | 729 | ||
720 | present_leaves_cluster_but_not_new_leaf: | ||
721 | /* All the old leaves cluster in the same slot, but the new leaf wants | ||
722 | * to go into a different slot, so we create a new node to hold the new | ||
723 | * leaf and a pointer to a new node holding all the old leaves. | ||
724 | */ | ||
725 | pr_devel("present leaves cluster but not new leaf\n"); | ||
726 | |||
727 | new_n0->back_pointer = node->back_pointer; | ||
728 | new_n0->parent_slot = node->parent_slot; | ||
729 | new_n0->nr_leaves_on_branch = node->nr_leaves_on_branch; | ||
730 | new_n1->back_pointer = assoc_array_node_to_ptr(new_n0); | ||
731 | new_n1->parent_slot = edit->segment_cache[0]; | ||
732 | new_n1->nr_leaves_on_branch = node->nr_leaves_on_branch; | ||
733 | edit->adjust_count_on = new_n0; | ||
734 | |||
735 | for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++) | ||
736 | new_n1->slots[i] = node->slots[i]; | ||
737 | |||
738 | new_n0->slots[edit->segment_cache[0]] = assoc_array_node_to_ptr(new_n0); | ||
739 | edit->leaf_p = &new_n0->slots[edit->segment_cache[ASSOC_ARRAY_FAN_OUT]]; | ||
740 | |||
741 | edit->set[0].ptr = &assoc_array_ptr_to_node(node->back_pointer)->slots[node->parent_slot]; | ||
742 | edit->set[0].to = assoc_array_node_to_ptr(new_n0); | ||
743 | edit->excised_meta[0] = assoc_array_node_to_ptr(node); | ||
744 | pr_devel("<--%s() = ok [insert node before]\n", __func__); | ||
745 | return true; | ||
746 | |||
747 | all_leaves_cluster_together: | 730 | all_leaves_cluster_together: |
748 | /* All the leaves, new and old, want to cluster together in this node | 731 | /* All the leaves, new and old, want to cluster together in this node |
749 | * in the same slot, so we have to replace this node with a shortcut to | 732 | * in the same slot, so we have to replace this node with a shortcut to |