Lindenii Project Forge
slice_sorted: Incrementally preserve sorting instead of always resorting
use sort; // Deletes an item from a [[map]]. Returns the removed value or void. export fn del(m: *map, key: []u8) (*opaque | void) = { let dummy = 0; let probe = (key, (&dummy: *opaque)); match (sort::search((m.items: []const opaque), size(([]u8, *opaque)), (&probe: const *opaque), &cmp_kv)) { case let idx: size => let v = m.items[idx].1; delete(m.items[idx]);
resort(m);
return v; case void => return; }; };
use sort;
fn cmp_kv(a: const *opaque, b: const *opaque) int = { let ka = (*(a: *([]u8, *opaque))).0; let kb = (*(b: *([]u8, *opaque))).0; return keycmp(ka, kb); }; fn keycmp(a: []u8, b: []u8) int = { let n = if (len(a) < len(b)) len(a) else len(b); for (let i = 0z; i < n; i += 1) { if (a[i] < b[i]) return -1; if (a[i] > b[i]) return 1; }; if (len(a) < len(b)) return -1; if (len(a) > len(b)) return 1; return 0; };
fn resort(m: *map) void = { sort::inplace((m.items: []opaque), size(([]u8, *opaque)), &cmp_kv); };
use sort; // Sets an item in a [[map]], replacing any existing item with the same key. export fn set(m: *map, key: []u8, value: *opaque) (void | nomem) = { let dummy = 0; let probe = (key, (&dummy: *opaque));
match (sort::search((m.items: []const opaque), size(([]u8, *opaque)), (&probe: const *opaque), &cmp_kv)) { case let idx: size => m.items[idx].1 = value; case void =>
append(m.items, (key, value))?;
let ins = sort::lbisect((m.items: []const opaque), size(([]u8, *opaque)), (&probe: const *opaque), &cmp_kv); insert(m.items[ins], (key, value))?;
};
resort(m);
};