tinysetqueue
tinysetqueue is a stack-allocated queue with configurable FIFO or LIFO processing and built-in membership tracking for dense integer domains. It eliminates duplicate work while keeping latency and memory usage predictable—ideal for embedded, no_std, and data-structure heavy workloads such as BFS, frontier expansion, and constraint propagation.
Highlights
- Allocation-free API uses caller-provided ring-buffer storage
- Toggle FIFO or LIFO behavior per queue via
ProcessingOrder - Direct-mapped membership bitmap deduplicates enqueues in O(1)
- Two membership modes:
InQueue(requeue after pop) andVisited(ban after first insert) - Fully compatible with
no_std - Works with
[bool]backings for speed or[u64]bitsets for dense domains - Zero external dependencies and zero unsafe code
Quick Start
use ;
// Note: The item type T must implement Copy + Into<usize>
const CAPACITY: usize = 16;
const DOMAIN: usize = 64;
let mut buf = ;
let mut membership = ;
let mut queue = new;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!; // membership cleared by pop
Usage in no_std Environments
This crate is fully compatible with no_std contexts. To use it in embedded or bare-metal projects, disable the default features (which include std) in your Cargo.toml:
[]
= { = "0.3.0", = false }
If you want the clear_on_new behavior (recommended) but not std:
[]
= { = "0.3.0", = false, = ["clear_on_new"] }
The API remains identical. Since the queue relies entirely on caller-provided stack/static memory, no global allocator (alloc) is required.
Choosing a Backing
TinySetQueue accepts any membership storage that implements its sealed SetBacking trait. Supply the backing that best matches your constraints:
use ;
let mut buf = ;
// Fast path: 1 byte per element.
let mut bitmap = ;
let mut queue = new;
// Memory-dense path: 1 bit per element (requires domain <= 64 * backing.len()).
let mut bitset = ;
let mut dense_queue = new;
Both queues share the same API; the compiler infers the correct backing behavior from the slice you pass.
Usage Notes
- This is a direct-mapped queue: keys must map densely into
0..DOMAIN. If you pushid.into() == 1_000_000, yourin_queueslice must be at least that long. For sparse identifiers, consider remapping or using a different data structure such asHashSet. - By default
TinySetQueue::newclears the membership bitmap for you (featureclear_on_new). Disable it if you need to preserve pre-seeded membership data. MembershipMode::Visitedkeeps membership markers set after popping. This makes the queue behave like a hybrid queue/set that only schedules each element once.- Select FIFO or LIFO semantics per queue by passing the desired
ProcessingOrdertoTinySetQueue::new. - Reuse the queue by calling
clearto reset membership and indices without reallocating. - By default the crate compiles in
no_stdmode. Enable thestdfeature to integrate with standard-library environments without needing#![no_std]in your binary.
When to Reach for tinysetqueue
- BFS, Dijkstra-lite, IDA*, or flood-fill algorithms on microcontrollers
- Cellular automata or constraint propagation where duplicate work must be suppressed
- Graph traversals keyed by dense integer handles (entity/component IDs, array offsets)
- Simulation step scheduling where memory predictability matters as much as time
Feature Flags
std(default) — Pulls in the standard library so the crate can be used without a#![no_std]consumer.clear_on_new(default) — Automatically zeroes the membership bitmap insideTinySetQueue::new. Disable to keep caller-supplied membership state.pow2— Enables the bit-maskingTinySetQueuePow2variant for power-of-two capacities.
Power-of-Two Variant
For workloads that need the lowest possible overhead on fixed-length buffers, enable the pow2 feature and use TinySetQueuePow2. This variant requires the queue capacity to be a power of two and replaces the % arithmetic with very fast bit masking. The feature gate keeps the default build lean for users who do not need the specialized path; flip it on when you opt into the stricter buffer requirement and the extra code is worth the saved cycles. Activate it with --features pow2 when building or testing.
#
#
If the buffer length is not a power of two, the constructor panics.
License
Licensed under either of
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate is licensed as described above.
When adding changes, please run tests in both configurations to cover the clear_on_new feature toggle: