From 5b01423f06103e2b09f42bf59d0532e39c70569d Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Wed, 17 Sep 2025 01:43:19 +0800 Subject: [PATCH] Fix some btree and swiss bugs o Handle case where key is equal to promoted median after splitting full child o Descend with new index after merging children o Fix weird slice alloc bug in swiss --- ds/map/btree/internal.ha | 16 ++++++++++++---- ds/map/swiss/internal.ha | 2 +- ds/map/swiss/new.ha | 2 +- diff --git a/ds/map/btree/internal.ha b/ds/map/btree/internal.ha index f16cbd67dc5dde90ef5986204157120af2aed0c5..d73038ca42922c5f9957db12c1c1d895742126ef 100644 --- a/ds/map/btree/internal.ha +++ b/ds/map/btree/internal.ha @@ -88,10 +88,14 @@ }; if (len(x.children[i].keys) == 2 * m.t - 1) { split_child(m, x, i)?; - if (cmp_u8slice((&key: const *opaque), - (&x.keys[i]: const *opaque)) > 0) { - insert_nonfull(m, x.children[i + 1], key, val)?; + let cmp = cmp_u8slice((&key: const *opaque), + (&x.keys[i]: const *opaque)); + if (cmp == 0) { + x.vals[i] = val; return; + }; + if (cmp > 0) { + i += 1; }; }; insert_nonfull(m, x.children[i], key, val)?; @@ -169,8 +173,9 @@ fn pop_max(m: *map, x: *node) ([]u8, *opaque) = { let cur = x; for (!cur.leaf) { + let last_before = len(cur.children) - 1; + ensure_child_has_space(m, cur, last_before); let last = len(cur.children) - 1; - ensure_child_has_space(m, cur, last); cur = cur.children[last]; }; let k = cur.keys[len(cur.keys) - 1]; @@ -232,5 +237,8 @@ return; }; ensure_child_has_space(m, x, i); + if (i >= len(x.children)) { + i = len(x.children) - 1; + }; return delete_rec(m, x.children[i], key); }; diff --git a/ds/map/swiss/internal.ha b/ds/map/swiss/internal.ha index 125d034d0a24993150dcc2ddba968efd2fae14fb..54f58aa847472d3f30927b3dab897738807e56df 100644 --- a/ds/map/swiss/internal.ha +++ b/ds/map/swiss/internal.ha @@ -72,7 +72,7 @@ }; fn resize(m: *map, new_groups_len: size) (void | nomem) = { if (new_groups_len == 0) new_groups_len = 1; - let gs: []group = match (alloc([group{...}...]: []group, new_groups_len)) { + let gs = match (alloc([group{...}...], new_groups_len)) { case let a: []group => yield a; case nomem => return nomem; }; diff --git a/ds/map/swiss/new.ha b/ds/map/swiss/new.ha index 3a342c40296ed4480531407086c945826cdfadaf..f10e0bce9ccb96bf0b60bad0c11b4c2a857c2fc4 100644 --- a/ds/map/swiss/new.ha +++ b/ds/map/swiss/new.ha @@ -22,7 +22,7 @@ v *= 2; }; let groups_count = v; - let gs: []group = match (alloc([group{...}...]: []group, groups_count)) { + let gs = match (alloc([group{...}...], groups_count)) { case let a: []group => yield a; case nomem => return nomem; }; -- 2.48.1