Representations¶
The containers a Store can resolve to live in include/urd/repr, which code that uses a Store never includes:
requests use only the vocabulary of urd/tags.hpp and urd/spec.hpp. Each container has a declaration
(include/urd/repr/<kind>/*_fwd.hpp): its kind, what it provides, what it relies_on (what a request must
state, and by role the type traits of its data), what Stores held as its elements get, its operation_costs and
its words. container_traits is derived from it, and the typed tests check every declared property against a
reference model through thousands of random operations; a deliberately wrong declaration is caught. How to add a
container, or a kind, is on Extending urd.
Headers¶
urd/store.hpp declares the representations and defines none (include/urd/repr/<kind>/*_fwd.hpp: the declaration,
its defaults, and the header that defines it; include/urd/registry/declarations.hpp lists them by kind), and a
request names only the container it resolves to. A
file includes the header of each container its Stores resolve to, in urd/repr/, and nothing grouped; a Store whose
container’s header is missing fails to compile naming the headers to include, a wrapper’s part before the wrapper.
docs/RESOLUTION.md gives each request’s headers.
Header ( |
Defines |
Pulls in |
|---|---|---|
|
the bitset, the sparse set, the slot-per-index maps |
nothing |
|
the partition |
nothing |
|
the multimaps by key index |
nothing |
|
the postings (values together per key in a hash table) |
gtl |
|
the insertion-ordered map (with its keys’ header) |
nothing |
|
|
nothing |
|
rows flattened into one array, rows kept for reuse |
nothing |
|
the standard’s node containers and the recycling wrappers |
nothing |
|
first in (deque or ring), last in, the least first |
nothing |
|
gtl’s flat hash tables |
gtl |
|
the indexed sets (interners) |
gtl |
|
Boost’s flat sorted containers |
Boost.Container |
|
the row interner, the tree pools, the slot vector |
gtl |
|
the record interner and the arena interner |
gtl, cista |
|
the scoped map (with the scoped map’s header) |
nothing |
|
layered dense maps and pools (with the layered container’s header) |
nothing |
|
gtl’s sharded tables |
gtl |
The standard library’s and Boost’s¶
std::vector, std::set, std::multiset, std::map, std::multimap, std::unordered_set,
std::unordered_map, std::unordered_multimap, gtl::flat_hash_set, gtl::flat_hash_map,
boost::container::flat_set, flat_multiset, flat_map, flat_multimap, and with gtl
gtl::parallel_flat_hash_set, parallel_flat_hash_map and their node-based twins, each with urd’s urd::Hash,
urd::EqualTo and urd::Less.
urd’s own¶
Container |
What it is |
Serves |
|---|---|---|
|
a bitset over the key range; with word tracking, a clear that touches only the words set |
|
|
Briggs–Torczon: n keys plus U positions, O(1) clear; optionally in insertion order |
|
|
a slot per index; with generations, an O(1) clear; over segments, values that never move; with a spin lock per slot too, thread-safe updates |
|
|
a vector plus a flat hash table of positions; the concurrent one over segments that never move |
|
|
a key set in insertion order beside its values |
|
|
a flat hash table of value vectors |
|
|
compressed sparse rows; with the in-edges too |
|
|
a vector of values per index, growing |
|
|
rows in one array per level; rows kept with their storage for reuse |
|
|
a map that keeps erased nodes and their values for the next keys; a node set that keeps erased nodes |
maps of |
|
deque, vector or binary heap; a heap of handles; a bucket per priority |
queues |
|
rows stored once in full; as trees sharing subtrees; slots reused after erase |
pools |
|
records stored once, in an indexed set or serialized into a byte arena |
|
|
a pool, or a dense map (thread-safe over the thread-safe generation map), over a parent |
|
|
a map with a log of previous values; union-find; a vector of doubling segments |
|
Order of preference¶
The registry lists the candidates in an order backed by Benchmarks: an open-addressing hash table first
wherever order is not asked for, node-based tables for stable_refs, a tree where order is asked for over
elements inserted over time, the dense containers after the hash tables (and only a request that promises
dense reaches them at all: a container that stores by index demands keys that are indices, whatever its place
in the list), the indexed set after them, pools and queues by their kind. Where a request is small or frozen,
containers with stable storage (a node per element, or segments) move last. What a request resolves to shows what every
request of a grid resolves to; a test audits
that the chosen container gives no more costly guarantees nobody asked for than another serving one, listing the
intended exceptions.