Lindenii Project Forge
Add iter
// SPDX-License-Identifier: MPL-2.0 use ds::map; export type iterator = struct { vt: map::iterator, nodes: []*node, idxs: []size, visit_key: []bool, }; const _itvt: map::vtable_iterator = map::vtable_iterator { nexter = &vt_next, }; fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator); export fn iter(m: *map) (*map::iterator | nomem) = { let it = alloc(iterator { vt = &_itvt, nodes = [], idxs = [], visit_key = [], })?; match (append(it.nodes, m.root)) { case void => void; case nomem => return nomem; }; match (append(it.idxs, 0z)) { case void => void; case nomem => return nomem; }; match (append(it.visit_key, false)) { case void => void; case nomem => return nomem; }; return (it: *map::iterator); }; export fn next(it: *iterator) (([]u8, *opaque) | done) = { for (len(it.nodes) != 0) { let top = len(it.nodes) - 1; let x = it.nodes[top]; let i = it.idxs[top]; let vk = it.visit_key[top]; if (x.leaf) { if (i < len(x.keys)) { it.idxs[top] = i + 1; return (x.keys[i], x.vals[i]); }; delete(it.nodes[top]); delete(it.idxs[top]); delete(it.visit_key[top]); continue; }; if (vk) { if (i >= len(x.keys)) { it.visit_key[top] = false; continue; }; it.visit_key[top] = false; it.idxs[top] = i + 1; return (x.keys[i], x.vals[i]); }; if (i < len(x.keys)) { match (append(it.nodes, x.children[i])) { case void => void; case nomem => abort("btree::iter: nomem"); }; match (append(it.idxs, 0z)) { case void => void; case nomem => abort("btree::iter: nomem"); }; match (append(it.visit_key, false)) { case void => void; case nomem => abort("btree::iter: nomem"); }; it.visit_key[top] = true; continue; }; if (i == len(x.keys)) { match (append(it.nodes, x.children[i])) { case void => void; case nomem => abort("btree::iter: nomem"); }; match (append(it.idxs, 0z)) { case void => void; case nomem => abort("btree::iter: nomem"); }; match (append(it.visit_key, false)) { case void => void; case nomem => abort("btree::iter: nomem"); }; it.idxs[top] = i + 1; continue; }; delete(it.nodes[top]); delete(it.idxs[top]); delete(it.visit_key[top]); }; return done; };
// SPDX-License-Identifier: MPL-2.0 use ds::map; // B-tree-based map from []u8 to *opaque. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, // Min degree t: size, root: *node, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org> // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; export type iterator = struct { vt: map::iterator, m: *map, bi: size, cur: nullable *map::iterator, }; const _itvt: map::vtable_iterator = map::vtable_iterator { nexter = &vt_next, }; fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator); export fn iter(m: *map) (*map::iterator | nomem) = { let it = alloc(iterator { vt = &_itvt, m = m, bi = 0, cur = null, })?; for (it.bi < m.n) { let b = m.buckets[it.bi]; it.bi += 1; match (map::iter(b)) { case let i: *map::iterator => it.cur = i; break; case nomem => abort("hashmap::iter: nomem"); }; }; return (it: *map::iterator); }; export fn next(it: *iterator) (([]u8, *opaque) | done) = { for (true) { match (it.cur) { case null => if (it.bi >= it.m.n) return done; let b = it.m.buckets[it.bi]; it.bi += 1; match (map::iter(b)) { case let i: *map::iterator => it.cur = i; case nomem => abort("hashmap::iter: nomem"); }; case let curi: *map::iterator => match (map::next(curi)) { case let kv: ([]u8, *opaque) => return kv; case done => it.cur = null; }; }; }; };
// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org> // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; // A simple hash map from []u8 to *opaque pointers, using the user-provided hash // and collision resolution function. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, n: size, buckets: []*map::map, hash64: *fn(hash_params: nullable *opaque, key: []u8) size, hash_params: nullable *opaque, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org> // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; export type iterator = map::iterator; export fn iter(m: *map) (*map::iterator | nomem) = { return map::iter(m.inner); };
// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org> // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; // A simple hash map from byte strings to opaque pointers, using FNV for // hashing and fallback maps for collision resolution. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, inner: *map::map, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org> // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; export type iterator = map::iterator; export fn iter(m: *map) (*map::iterator | nomem) = { return map::iter(m.inner); };
// SPDX-License-Identifier: MPL-2.0 // SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org> // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; // A simple hash map from byte strings to opaque pointers, using SipHash for // hashing and fallback maps for collision resolution. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, inner: *map::map, key: *[16]u8, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// A map is a pointer to a [[vtable]] which allows for map types to implement // common operations. export type map = *vtable;
// Iterator vtable for map iteration. export type vtable_iterator = struct { nexter: *nexter, }; // The outward-facing iterator type (pointer to an iterator vtable). export type iterator = *vtable_iterator;
// The vtable type defines a set of virtual functions for a [[map]]. export type vtable = struct { getter: *getter, setter: *setter, deleter: *deleter, finisher: *finisher,
iter: *iterer,
}; // The interface for a map which could be used to get values. Returns either a // pointer to the value, or void if the key does not exist. export type getter = fn(m: *map, key: []u8) (*opaque | void); // Gets an item from a [[map]]. Returns a pointer to the value or void. export fn get(m: *map, key: []u8) (*opaque | void) = { return m.getter(m, key); }; // The interface for a map which could be used to set values. Returns void on // success, or nomem if memory allocation failed. If the value already exists, // it is replaced. export type setter = fn(m: *map, key: []u8, value: *opaque) (void | nomem); // 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) = { return m.setter(m, key, value); }; // The interface for a map which could be used to delete values. Returns a // pointer to the deleted value, or void if the key does not exist. export type deleter = fn(m: *map, key: []u8) (*opaque | void); // Deletes an item from a [[map]]. Returns the removed value or void. export fn del(m: *map, key: []u8) (*opaque | void) = { return m.deleter(m, key); }; // The interface for a map which requires a finisher function to free it. export type finisher = fn(m: *map) void; // Frees the map and all of its resources. Do not use the map after calling. export fn finish(m: *map) void = { m.finisher(m); };
// Iterator maker function in the main vtable. export type iterer = fn(m: *map) (*iterator | nomem); // Creates an iterator for this map implementation. export fn iter(m: *map) (*iterator | nomem) = { return m.iter(m); }; // Iterator "next" method signature. // Returns the next (key, value) pair, or done when iteration is complete. export type nexter = fn(it: *iterator) (([]u8, *opaque) | done); // Advances the iterator, yielding (key, value) or done when finished. export fn next(it: *iterator) (([]u8, *opaque) | done) = { return it.nexter(it); };
// SPDX-License-Identifier: MPL-2.0 use ds::map; export type iterator = struct { vt: map::iterator, cur: nullable *node, }; const _itvt: map::vtable_iterator = map::vtable_iterator { nexter = &vt_next, }; fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator); export fn iter(m: *map) (*map::iterator | nomem) = { let start: nullable *node = match (m.root) { case null => yield null; case let r: *node => yield subtree_min(r); }; let it = alloc(iterator { vt = &_itvt, cur = start, })?; return (it: *map::iterator); }; fn successor(n0: *node) nullable *node = { let n = n0; match (n.right) { case let r: *node => return subtree_min(r); case null => void; }; let mut_p: nullable *node = n.parent; let child: nullable *node = n; for (mut_p != null) { let p = match (mut_p) { case let pp: *node => yield pp; case null => break; }; if (p.right != child) { return p; }; child = p; mut_p = p.parent; }; return null; }; export fn next(it: *iterator) (([]u8, *opaque) | done) = { match (it.cur) { case null => return done; case let n: *node => let k = n.key; let v = n.val; it.cur = successor(n); return (k, v); }; };
use ds::map; // Red–black tree-based map from []u8 to *opaque. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, root: nullable *node, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: MPL-2.0 use ds::map; export type iterator = struct { vt: map::iterator, m: *map, i: size, }; const _itvt: map::vtable_iterator = map::vtable_iterator { nexter = &vt_next, }; fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator); export fn iter(m: *map) (*map::iterator | nomem) = { let it = alloc(iterator { vt = &_itvt, m = m, i = 0, })?; return (it: *map::iterator); }; export fn next(it: *iterator) (([]u8, *opaque) | done) = { if (it.i >= len(it.m.items)) { return done; }; let kv = it.m.items[it.i]; it.i += 1; return (kv.0, kv.1); };
// SPDX-License-Identifier: MPL-2.0 use ds::map; // Slice-backed map from []u8 to *opaque using linear scanning. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, items: []([]u8, *opaque), }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: MPL-2.0 use ds::map; export type iterator = struct { vt: map::iterator, m: *map, i: size, }; const _itvt: map::vtable_iterator = map::vtable_iterator { nexter = &vt_next, }; fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator); export fn iter(m: *map) (*map::iterator | nomem) = { let it = alloc(iterator { vt = &_itvt, m = m, i = 0, })?; return (it: *map::iterator); }; export fn next(it: *iterator) (([]u8, *opaque) | done) = { if (it.i >= len(it.m.items)) { return done; }; let kv = it.m.items[it.i]; it.i += 1; return (kv.0, kv.1); };
// SPDX-License-Identifier: MPL-2.0 use ds::map; // Sorted slice backed map from []u8 to *opaque. // Keys are ordered byte-wize lexicgraphically. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, items: []([]u8, *opaque), }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: Apache-2.0 AND MPL-2.0 // SPDX-FileCopyrightText: 2024 The Cockroach Authors // SPDX-FileCopyrightText: 2025 Runxi Yu use ds::map; export type iterator = struct { vt: map::iterator, m: *map, gi: size, si: size, }; const _itvt: map::vtable_iterator = map::vtable_iterator { nexter = &vt_next, }; fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator); export fn iter(m: *map) (*map::iterator | nomem) = { let it = alloc(iterator { vt = &_itvt, m = m, gi = 0, si = 0, })?; return (it: *map::iterator); }; export fn next(it: *iterator) (([]u8, *opaque) | done) = { if (len(it.m.groups) == 0) return done; for (it.gi <= it.m.group_mask) { for (let g = &it.m.groups[it.gi]; it.si < GROUP_SIZE; it.si += 1) { let c = g.ctrl[it.si]; if (!is_full_ctrl(c)) { continue; }; let k = g.keys[it.si]; let v = g.vals[it.si]; it.si += 1; match (v) { case null => abort("map: null internal state escaped"); case let p: *opaque => return (k, p); }; }; it.gi += 1; it.si = 0; }; return done; };
// SPDX-FileCopyrightText: 2024 The Cockroach Authors // SPDX-FileCopyrightText: 2025 Runxi Yu use ds::map; // Generic map based on swiss tables from []u8 to *opaque. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, group_mask: size, used: size, tombs: size, hash64: *fn(hash_params: nullable *opaque, key: []u8) size, hash_params: nullable *opaque, groups: []group, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: Apache-2.0 AND MPL-2.0 // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; export type iterator = map::iterator; export fn iter(m: *map) (*map::iterator | nomem) = { return map::iter(m.inner); };
// SPDX-License-Identifier: Apache-2.0 AND MPL-2.0 // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; // Swiss-table based map from []u8 to *opaque, using FNV-1a. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, inner: *map::map, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);
// SPDX-License-Identifier: Apache-2.0 AND MPL-2.0 // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; export type iterator = map::iterator; export fn iter(m: *map) (*map::iterator | nomem) = { return map::iter(m.inner); };
// SPDX-License-Identifier: Apache-2.0 AND MPL-2.0 // SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org> use ds::map; // Swiss-table based map from []u8 to *opaque, using SipHash. // // You are advised to create these with [[new]]. export type map = struct { vt: map::map, inner: *map::map, key: *[16]u8, }; const _vt: map::vtable = map::vtable { getter = &vt_get, setter = &vt_set, deleter = &vt_del, finisher = &vt_finish,
iter = &vt_iter,
}; fn vt_get(m: *map::map, key: []u8) (*opaque | void) = get(m: *map, key); fn vt_set(m: *map::map, key: []u8, v: *opaque) (void | nomem) = set(m: *map, key, v); fn vt_del(m: *map::map, key: []u8) (*opaque | void) = del(m: *map, key); fn vt_finish(m: *map::map) void = finish(m: *map);
fn vt_iter(m: *map::map) (*map::iterator | nomem) = iter(m: *map);