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 |
