Skip to content

BTreeMap insert does not honor the B-tree invariant #74834

Closed
@ssomers

Description

@ssomers

Inserting into a BTreeMap, where the key lands in a node that is full (has 11 elements), cause that node to keep 6 elements and split off 5 elements, of which one ends up in the parent node, and the other 4 in a new node. If the key inserted is not big and belongs among the left side of the keys in the node, the left child comes out with 7 elements and the right child has only 4 elements.

I don't think(*) this causes any observable ugliness so it's impossible to demonstrate using outsider testing code. Maybe through memory footprint or performance analysis. I have a commit peeking at the internals to prove it.

Is this really a bug at all?

  • The documentation writes that "each node contain B-1 to 2B-1 elements", like other texts on B trees
    (where B-1 = MIN_LEN = 5).
  • The code too wants to assure that any non-root node is not underfull, i.e. carrying less than MIN_LEN elements.
  • But it's possible that this strategy enhances performance, because often keys inserted are generally increasing, so they tend to land in the right child and leave less wasted space in the leftmost nodes.

(*) For instance, you can't reduce the number of elements further. remove_kv_tracking could temporarily reduce it down to 3, but it will then either merge with a sibling or be stocked back up to 4 elements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-collectionsArea: `std::collections`C-bugCategory: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions