use crate::{KeyStore, TrieKey};
use std::simd::{Simd, cmp::SimdPartialEq};
const LEAF_BIT: u32 = 1u32 << 31;
const TERMINAL_BIT: u32 = 1u32 << 31;
const TERMINAL_POS: u8 = 2;
#[derive(Clone, Copy)]
struct Node {
children: [u32; 2],
prefix_lens: [u16; 2],
leaf: u32,
}
impl Node {
fn new() -> Self {
Node {
children: [0; 2],
prefix_lens: [0; 2],
leaf: 0,
}
}
#[inline]
fn is_leaf(&self, bit: usize) -> bool {
debug_assert!(bit < 2);
(self.children[bit] & LEAF_BIT) != 0
}
#[inline]
fn child_index(&self, bit: usize) -> u32 {
debug_assert!(bit < 2);
self.children[bit] & !LEAF_BIT
}
#[inline]
fn is_empty(&self, bit: usize) -> bool {
debug_assert!(bit < 2);
self.children[bit] == 0
}
#[inline]
fn set_leaf_child(&mut self, bit: usize, key_index: u32, prefix_len: u16) {
debug_assert!(bit < 2);
debug_assert!(key_index > 0, "key index 0 is the dummy");
self.children[bit] = key_index | LEAF_BIT;
self.prefix_lens[bit] = prefix_len;
}
#[inline]
fn set_internal_child(&mut self, bit: usize, arena_index: u32, prefix_len: u16) {
debug_assert!(bit < 2);
debug_assert!(arena_index > 0);
self.children[bit] = arena_index; self.prefix_lens[bit] = prefix_len;
}
#[inline]
fn leaf_key_index(&self, bit: usize) -> Option<u32> {
debug_assert!(bit < 2);
if self.is_leaf(bit) {
let idx = self.child_index(bit);
if idx != 0 {
return Some(idx);
}
}
None
}
#[inline]
fn is_terminal(&self) -> bool {
(self.leaf & TERMINAL_BIT) != 0
}
#[inline]
fn set_terminal(&mut self, val: bool) {
if val {
self.leaf |= TERMINAL_BIT;
} else {
self.leaf &= !TERMINAL_BIT;
}
}
#[inline]
fn leaf_key_index_val(&self) -> u32 {
self.leaf & !TERMINAL_BIT
}
#[inline]
fn set_leaf_key_index(&mut self, idx: u32) {
debug_assert!(idx > 0, "key index 0 is the dummy");
self.leaf = (self.leaf & TERMINAL_BIT) | idx;
}
}
impl std::fmt::Debug for Node {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let active: Vec<(usize, &str, u32, u16)> = (0..2)
.filter(|&b| self.children[b] != 0)
.map(|b| {
let tag = if self.is_leaf(b) { "L" } else { "I" };
let idx = self.child_index(b);
(b, tag, idx, self.prefix_lens[b])
})
.collect();
f.debug_struct("Node")
.field("prefix_lens", &self.prefix_lens)
.field("terminal", &self.is_terminal())
.field("leaf_idx", &self.leaf_key_index_val())
.field("children", &active)
.finish()
}
}
#[derive(Clone)]
pub struct BitTrie<K: TrieKey, V> {
arena: Vec<Node>,
keys: K::Store,
values: Vec<V>,
root_prefix_len: u16,
}
enum DivergeResult {
Duplicate,
At(usize),
}
#[inline]
fn prefix_matches(key_a: &[u8], key_b: &[u8], from: usize, to: usize) -> bool {
if key_a.len() * 8 < to || key_b.len() * 8 < to {
return false;
}
let from_byte = from / 8;
let to_byte = (to + 7) / 8; let min_len = key_a.len().min(key_b.len()).min(to_byte);
for i in from_byte..min_len {
if key_a[i] != key_b[i] {
let xor = key_a[i] ^ key_b[i];
let first_diff_bit = i * 8 + xor.leading_zeros() as usize;
return first_diff_bit >= to;
}
}
true
}
#[inline]
fn find_divergence(key_a: &[u8], key_b: &[u8], from: usize) -> DivergeResult {
let total_a = key_a.len() * 8;
let total_b = key_b.len() * 8;
let min = total_a.min(total_b);
let mut d = from;
while d < min {
if key_bit_at(key_a, d) != key_bit_at(key_b, d) {
return DivergeResult::At(d);
}
d += 1;
}
if total_a == total_b {
DivergeResult::Duplicate
} else {
DivergeResult::At(d)
}
}
#[inline]
fn diverging_bit(xor: u8, byte_idx: usize) -> usize {
byte_idx * 8 + xor.leading_zeros() as usize
}
fn simd_find_divergence<const N: usize>(key_a: &[u8], key_b: &[u8], from: usize) -> DivergeResult
{
let minlen = key_a.len().min(key_b.len());
let mut i = from / 8;
while i + N <= minlen {
let a = Simd::<u8, N>::from_slice(unsafe { key_a.get_unchecked(i..i + N) });
let b = Simd::<u8, N>::from_slice(unsafe { key_b.get_unchecked(i..i + N) });
let mask = a.simd_ne(b);
if mask.any() {
let diff_byte_idx = i + mask.first_set().unwrap();
let xor = unsafe { *key_a.get_unchecked(diff_byte_idx) ^ *key_b.get_unchecked(diff_byte_idx) };
return DivergeResult::At(diverging_bit(xor, diff_byte_idx));
}
i += N;
}
find_divergence(key_a, key_b, i * 8)
}
#[inline]
fn simd_eq(a: &[u8], b: &[u8]) -> bool {
if a.len() != b.len() {
return false;
}
let len = a.len();
let mut i = 0;
while i + 16 <= len {
let va = Simd::<u8, 16>::from_slice(unsafe { a.get_unchecked(i..i + 16) });
let vb = Simd::<u8, 16>::from_slice(unsafe { b.get_unchecked(i..i + 16) });
if va.simd_ne(vb).any() {
return false;
}
i += 16;
}
while i < len {
if unsafe { *a.get_unchecked(i) != *b.get_unchecked(i) } {
return false;
}
i += 1;
}
true
}
#[inline]
fn key_bit_at(key: &[u8], idx: usize) -> u8 {
let byte_idx = idx / 8;
if byte_idx < key.len() {
(key[byte_idx] >> (7 - idx % 8)) & 1
} else {
0
}
}
impl<K: TrieKey, V> BitTrie<K, V> {
pub fn new() -> Self {
BitTrie {
arena: Vec::new(),
keys: K::Store::default(),
values: Vec::new(),
root_prefix_len: 0,
}
}
pub fn len(&self) -> usize {
self.keys.len()
}
pub fn is_empty(&self) -> bool {
self.keys.len() == 0
}
#[inline]
pub fn get_index(&self, key: &[u8]) -> Option<usize> {
if self.arena.is_empty() {
return None;
}
let max_bits = key.len() * 8;
let mut node_idx: u32 = 0;
let mut prefix_len = self.root_prefix_len as usize;
loop {
let node = &self.arena[node_idx as usize];
if prefix_len >= max_bits {
if node.is_terminal() {
let ki = node.leaf_key_index_val();
let key_in_buf = self.keys.key_bytes(ki);
if simd_eq(key_in_buf, key) {
return Some(ki as usize);
}
}
return None;
}
let bit = key_bit_at(key, prefix_len) as usize;
let child = node.children[bit];
if child == 0 {
return None;
}
if child & LEAF_BIT != 0 {
let ki = child & !LEAF_BIT;
return if simd_eq(self.keys.key_bytes(ki), key) {
Some(ki as usize)
} else {
None
};
}
prefix_len = node.prefix_lens[bit] as usize;
node_idx = child;
}
}
pub fn get(&self, key: &[u8]) -> Option<&V> {
self.get_index(key).map(|idx| &self.values[idx - 1])
}
pub fn get_mut(&mut self, key: &[u8]) -> Option<&mut V> {
self.get_index(key).map(|idx| &mut self.values[idx - 1])
}
pub fn insert(&mut self, key: K, value: V) -> Result<usize, ()> {
let new_index = self.keys.push(key);
self.values.push(value);
let new_key = self.keys.key_bytes(new_index);
let max_bits = new_key.len() * 8;
if self.arena.is_empty() {
if max_bits == 0 {
let mut root = Node::new();
root.set_terminal(true);
root.set_leaf_key_index(new_index);
self.arena.push(root);
self.root_prefix_len = 0;
return Ok(new_index as usize);
}
let first_bit = key_bit_at(new_key, 0) as usize;
let mut root = Node::new();
root.set_leaf_child(first_bit, new_index, max_bits as u16);
root.set_leaf_key_index(new_index);
self.arena.push(root);
self.root_prefix_len = 0;
return Ok(new_index as usize);
}
let mut node_idx: u32 = 0;
let mut confirmed: usize = 0;
let mut prefix_len = self.root_prefix_len as usize;
let mut parent_info: Option<(u32, usize)> = None;
loop {
let node = &self.arena[node_idx as usize];
let ref_ki = node.leaf_key_index_val();
let ref_key = self.keys.key_bytes(ref_ki);
if prefix_matches(new_key, ref_key, confirmed, prefix_len) {
if max_bits <= prefix_len {
self.arena[node_idx as usize].set_terminal(true);
self.arena[node_idx as usize].set_leaf_key_index(new_index);
return Ok(new_index as usize);
}
let bit = key_bit_at(new_key, prefix_len) as usize;
let child = node.children[bit];
if child == 0 {
self.arena[node_idx as usize]
.set_leaf_child(bit, new_index, max_bits as u16);
return Ok(new_index as usize);
}
if child & LEAF_BIT != 0 {
let existing_ki = child & !LEAF_BIT;
let existing_key = self.keys.key_bytes(existing_ki);
let existing_prefix = node.prefix_lens[bit];
match simd_find_divergence::<8>(new_key, existing_key, confirmed) {
DivergeResult::Duplicate => {
self.keys.rollback();
let _ = self.values.pop();
return Err(());
}
DivergeResult::At(d) => {
let mut split_node = Node::new();
if d >= max_bits {
let exist_bit = key_bit_at(existing_key, d) as usize;
split_node.set_terminal(true);
split_node.set_leaf_key_index(new_index);
split_node.set_leaf_child(exist_bit, existing_ki, existing_prefix);
} else if d >= existing_key.len() * 8 {
let new_child_bit = key_bit_at(new_key, d) as usize;
split_node.set_terminal(true);
split_node.set_leaf_key_index(existing_ki);
split_node.set_leaf_child(new_child_bit, new_index, max_bits as u16);
} else {
let new_child_bit = key_bit_at(new_key, d) as usize;
let exist_bit = key_bit_at(existing_key, d) as usize;
debug_assert_ne!(new_child_bit, exist_bit);
split_node.set_leaf_child(new_child_bit, new_index, max_bits as u16);
split_node.set_leaf_child(exist_bit, existing_ki, existing_prefix);
split_node.set_leaf_key_index(existing_ki);
}
let split_idx = self.arena.len() as u32;
self.arena.push(split_node);
self.arena[node_idx as usize]
.set_internal_child(bit, split_idx, d as u16);
}
}
return Ok(new_index as usize);
}
confirmed = prefix_len + 1;
parent_info = Some((node_idx, bit));
prefix_len = node.prefix_lens[bit] as usize;
node_idx = child;
} else {
match simd_find_divergence::<8>(new_key, ref_key, confirmed) {
DivergeResult::Duplicate => {
self.keys.rollback();
let _ = self.values.pop();
return Err(());
}
DivergeResult::At(diverge) => {
debug_assert!(diverge < prefix_len, "prefix_matches said diverge but simd found no divergence before prefix_len");
let new_bit = key_bit_at(new_key, diverge) as usize;
let ref_bit = key_bit_at(ref_key, diverge) as usize;
let mut new_parent = Node::new();
new_parent.prefix_lens[ref_bit] = prefix_len as u16;
if diverge >= max_bits {
new_parent.set_terminal(true);
new_parent.set_leaf_key_index(new_index);
} else {
new_parent.set_leaf_child(new_bit, new_index, max_bits as u16);
new_parent.set_leaf_key_index(new_index);
}
let old_node = std::mem::replace(
&mut self.arena[node_idx as usize],
new_parent,
);
let old_idx = self.arena.len() as u32;
self.arena.push(old_node);
self.arena[node_idx as usize]
.set_internal_child(ref_bit, old_idx, prefix_len as u16);
if let Some((pidx, pbit)) = parent_info {
self.arena[pidx as usize].prefix_lens[pbit] = diverge as u16;
} else {
self.root_prefix_len = diverge as u16;
}
return Ok(new_index as usize);
}
}
}
}
}
pub fn iter(&self) -> Cursor<'_, K, V> {
Cursor::new(self)
}
pub fn iter_last(&self) -> Cursor<'_, K, V> {
Cursor::new_last(self)
}
pub fn iter_mut(&mut self) -> CursorMut<'_, K, V> {
CursorMut::new(self)
}
pub fn iter_mut_last(&mut self) -> CursorMut<'_, K, V> {
CursorMut::new_last(self)
}
pub fn into_keys_values(self) -> (Vec<K>, Vec<V>) {
let keys = self.keys.into_keys();
(keys, self.values)
}
}
impl<K: TrieKey, V> Default for BitTrie<K, V> {
fn default() -> Self {
Self::new()
}
}
pub struct Cursor<'a, K: TrieKey, V> {
trie: &'a BitTrie<K, V>,
stack: Vec<(u32, u8)>,
}
impl<'a, K: TrieKey, V> Cursor<'a, K, V> {
fn new(trie: &'a BitTrie<K, V>) -> Self {
if trie.arena.is_empty() {
return Cursor { trie, stack: Vec::new() };
}
Cursor { trie, stack: vec![(0, u8::MAX)] }
}
fn new_last(trie: &'a BitTrie<K, V>) -> Self {
if trie.arena.is_empty() {
return Cursor { trie, stack: Vec::new() };
}
let mut iter = Cursor { trie, stack: Vec::new() };
iter.descend_last(0);
iter
}
fn descend_first(&mut self, mut idx: u32) {
loop {
let node = &self.trie.arena[idx as usize];
if node.is_terminal() {
self.stack.push((idx, TERMINAL_POS));
return;
}
if !node.is_empty(0) {
self.stack.push((idx, 0));
if node.is_leaf(0) {
return;
} else {
idx = node.child_index(0);
continue;
}
}
if !node.is_empty(1) {
self.stack.push((idx, 1));
if node.is_leaf(1) {
return;
} else {
idx = node.child_index(1);
continue;
}
}
return;
}
}
fn descend_last(&mut self, mut idx: u32) {
loop {
let node = &self.trie.arena[idx as usize];
if !node.is_empty(1) {
self.stack.push((idx, 1));
if node.is_leaf(1) {
return;
} else {
idx = node.child_index(1);
continue;
}
}
if !node.is_empty(0) {
self.stack.push((idx, 0));
if node.is_leaf(0) {
return;
} else {
idx = node.child_index(0);
continue;
}
}
if node.is_terminal() {
self.stack.push((idx, TERMINAL_POS));
}
return;
}
}
pub fn current(&self) -> Option<(&[u8], &V)> {
let ki = self.current_index()?;
let key = self.trie.keys.key_bytes(ki as u32);
let value = &self.trie.values[ki - 1];
Some((key, value))
}
pub fn current_index(&self) -> Option<usize> {
let &(arena_idx, which) = self.stack.last()?;
if which == u8::MAX {
return None;
}
let node = &self.trie.arena[arena_idx as usize];
if which == TERMINAL_POS {
Some(node.leaf_key_index_val() as usize)
} else {
node.leaf_key_index(which as usize).map(|ki| ki as usize)
}
}
#[inline]
fn advance_next(&mut self) -> bool {
loop {
let (arena_idx, which) = match self.stack.pop() {
Some(v) => v,
None => return false,
};
if which == TERMINAL_POS {
let node = &self.trie.arena[arena_idx as usize];
if !node.is_empty(0) {
self.stack.push((arena_idx, 0));
if node.is_leaf(0) {
return true;
} else {
self.descend_first(node.child_index(0));
return true;
}
}
if !node.is_empty(1) {
self.stack.push((arena_idx, 1));
if node.is_leaf(1) {
return true;
} else {
self.descend_first(node.child_index(1));
return true;
}
}
continue;
}
if which == u8::MAX {
let node = &self.trie.arena[arena_idx as usize];
if node.is_terminal() {
self.stack.push((arena_idx, TERMINAL_POS));
return true;
}
for bit in 0..2u8 {
if !node.is_empty(bit as usize) {
self.stack.push((arena_idx, bit));
if node.is_leaf(bit as usize) {
return true;
} else {
self.descend_first(node.child_index(bit as usize));
return true;
}
}
}
continue;
}
let search_bit = which as usize + 1;
if search_bit < 2 {
let node = &self.trie.arena[arena_idx as usize];
if !node.is_empty(search_bit) {
self.stack.push((arena_idx, search_bit as u8));
if node.is_leaf(search_bit) {
return true;
} else {
self.descend_first(node.child_index(search_bit));
return true;
}
}
}
}
}
#[inline]
fn advance_prev(&mut self) -> bool {
loop {
let (arena_idx, which) = match self.stack.pop() {
Some(v) => v,
None => return false,
};
if which == TERMINAL_POS {
continue;
}
if which == u8::MAX {
continue;
}
let bit = which as usize;
if bit > 0 {
let prev_bit = bit - 1;
let node = &self.trie.arena[arena_idx as usize];
if !node.is_empty(prev_bit) {
self.stack.push((arena_idx, prev_bit as u8));
if node.is_leaf(prev_bit) {
return true;
} else {
self.descend_last(node.child_index(prev_bit));
return true;
}
}
}
if bit == 0 {
let node = &self.trie.arena[arena_idx as usize];
if node.is_terminal() {
self.stack.push((arena_idx, TERMINAL_POS));
return true;
}
}
}
}
#[inline]
pub fn next(&mut self) -> Option<(&[u8], &V)> {
if self.advance_next() { self.current() } else { None }
}
#[inline]
pub fn prev(&mut self) -> Option<(&[u8], &V)> {
if self.advance_prev() { self.current() } else { None }
}
#[inline]
pub fn next_index(&mut self) -> Option<usize> {
if self.advance_next() { self.current_index() } else { None }
}
#[inline]
pub fn prev_index(&mut self) -> Option<usize> {
if self.advance_prev() { self.current_index() } else { None }
}
pub fn seek(&mut self, key: &[u8]) -> Option<(&[u8], &V)> {
if self.trie.arena.is_empty() {
self.stack.clear();
return None;
}
self.stack.clear();
let mut node_idx: u32 = 0;
let mut prefix_len = self.trie.root_prefix_len as usize;
let max_bits = key.len() * 8;
loop {
let node = &self.trie.arena[node_idx as usize];
if prefix_len >= max_bits {
if node.is_terminal() {
self.stack.push((node_idx, TERMINAL_POS));
return self.current();
}
for bit in 0..2u8 {
if !node.is_empty(bit as usize) {
self.stack.push((node_idx, bit));
if node.is_leaf(bit as usize) {
return self.current();
} else {
self.descend_first(node.child_index(bit as usize));
return self.current();
}
}
}
return self.next();
}
let bit = key_bit_at(key, prefix_len) as usize;
let child = node.children[bit];
if child != 0 {
self.stack.push((node_idx, bit as u8));
if child & LEAF_BIT != 0 {
let ki = child & !LEAF_BIT;
let leaf_key = self.trie.keys.key_bytes(ki);
if leaf_key >= key {
return self.current();
}
return self.next();
} else {
prefix_len = node.prefix_lens[bit] as usize;
node_idx = child;
continue;
}
}
let other_bit = 1 - bit;
let other_child = node.children[other_bit];
if other_child != 0 && other_bit > bit {
self.stack.push((node_idx, other_bit as u8));
if other_child & LEAF_BIT != 0 {
return self.current();
} else {
self.descend_first(other_child);
return self.current();
}
}
if node.is_terminal() && bit == 0 {
let ki = node.leaf_key_index_val();
let term_key = self.trie.keys.key_bytes(ki);
if term_key >= key {
self.stack.push((node_idx, TERMINAL_POS));
return self.current();
}
}
loop {
let (parent_idx, parent_bit) = self.stack.pop()?;
if parent_bit == TERMINAL_POS || parent_bit == u8::MAX {
let parent = &self.trie.arena[parent_idx as usize];
for next_bit in 0..2u8 {
if !parent.is_empty(next_bit as usize) {
self.stack.push((parent_idx, next_bit));
if parent.is_leaf(next_bit as usize) {
return self.current();
} else {
self.descend_first(parent.child_index(next_bit as usize));
return self.current();
}
}
}
continue;
}
if parent_bit == 0 {
let parent = &self.trie.arena[parent_idx as usize];
if !parent.is_empty(1) {
self.stack.push((parent_idx, 1));
if parent.is_leaf(1) {
return self.current();
} else {
self.descend_first(parent.child_index(1));
return self.current();
}
}
}
}
}
}
}
pub struct CursorMut<'a, K: TrieKey, V> {
trie: &'a mut BitTrie<K, V>,
stack: Vec<(u32, u8)>,
}
impl<'a, K: TrieKey, V> CursorMut<'a, K, V> {
pub fn new(trie: &'a mut BitTrie<K, V>) -> Self {
if trie.arena.is_empty() {
return CursorMut { trie, stack: Vec::new() };
}
CursorMut { trie, stack: vec![(0, u8::MAX)] }
}
pub fn new_last(trie: &'a mut BitTrie<K, V>) -> Self {
let mut c = CursorMut { trie, stack: Vec::new() };
c.last();
c
}
fn descend_first(&mut self, mut idx: u32) {
loop {
let node = &self.trie.arena[idx as usize];
if node.is_terminal() {
self.stack.push((idx, TERMINAL_POS));
return;
}
if !node.is_empty(0) {
self.stack.push((idx, 0));
if node.is_leaf(0) {
return;
} else {
idx = node.child_index(0);
continue;
}
}
if !node.is_empty(1) {
self.stack.push((idx, 1));
if node.is_leaf(1) {
return;
} else {
idx = node.child_index(1);
continue;
}
}
return;
}
}
fn descend_last(&mut self, mut idx: u32) {
loop {
let node = &self.trie.arena[idx as usize];
if !node.is_empty(1) {
self.stack.push((idx, 1));
if node.is_leaf(1) {
return;
} else {
idx = node.child_index(1);
continue;
}
}
if !node.is_empty(0) {
self.stack.push((idx, 0));
if node.is_leaf(0) {
return;
} else {
idx = node.child_index(0);
continue;
}
}
if node.is_terminal() {
self.stack.push((idx, TERMINAL_POS));
}
return;
}
}
#[inline]
pub fn current(&mut self) -> Option<(&[u8], &mut V)> {
let ki = self.current_index()?;
let key = self.trie.keys.key_bytes(ki as u32);
let value = &mut self.trie.values[ki - 1];
Some((key, value))
}
#[inline]
pub fn current_index(&self) -> Option<usize> {
let &(arena_idx, which) = self.stack.last()?;
if which == u8::MAX {
return None;
}
let node = &self.trie.arena[arena_idx as usize];
if which == TERMINAL_POS {
Some(node.leaf_key_index_val() as usize)
} else {
node.leaf_key_index(which as usize).map(|ki| ki as usize)
}
}
#[inline]
fn advance_next(&mut self) -> bool {
loop {
let (arena_idx, which) = match self.stack.pop() {
Some(v) => v,
None => return false,
};
if which == TERMINAL_POS {
let node = &self.trie.arena[arena_idx as usize];
if !node.is_empty(0) {
self.stack.push((arena_idx, 0));
if node.is_leaf(0) {
return true;
} else {
self.descend_first(node.child_index(0));
return true;
}
}
if !node.is_empty(1) {
self.stack.push((arena_idx, 1));
if node.is_leaf(1) {
return true;
} else {
self.descend_first(node.child_index(1));
return true;
}
}
continue;
}
if which == u8::MAX {
let node = &self.trie.arena[arena_idx as usize];
if node.is_terminal() {
self.stack.push((arena_idx, TERMINAL_POS));
return true;
}
for bit in 0..2u8 {
if !node.is_empty(bit as usize) {
self.stack.push((arena_idx, bit));
if node.is_leaf(bit as usize) {
return true;
} else {
self.descend_first(node.child_index(bit as usize));
return true;
}
}
}
continue;
}
let search_bit = which as usize + 1;
if search_bit < 2 {
let node = &self.trie.arena[arena_idx as usize];
if !node.is_empty(search_bit) {
self.stack.push((arena_idx, search_bit as u8));
if node.is_leaf(search_bit) {
return true;
} else {
self.descend_first(node.child_index(search_bit));
return true;
}
}
}
}
}
#[inline]
fn advance_prev(&mut self) -> bool {
loop {
let (arena_idx, which) = match self.stack.pop() {
Some(v) => v,
None => return false,
};
if which == TERMINAL_POS {
continue;
}
if which == u8::MAX {
continue;
}
let bit = which as usize;
if bit > 0 {
let prev_bit = bit - 1;
let node = &self.trie.arena[arena_idx as usize];
if !node.is_empty(prev_bit) {
self.stack.push((arena_idx, prev_bit as u8));
if node.is_leaf(prev_bit) {
return true;
} else {
self.descend_last(node.child_index(prev_bit));
return true;
}
}
}
if bit == 0 {
let node = &self.trie.arena[arena_idx as usize];
if node.is_terminal() {
self.stack.push((arena_idx, TERMINAL_POS));
return true;
}
}
}
}
pub fn first(&mut self) -> Option<(&[u8], &mut V)> {
if self.trie.arena.is_empty() {
self.stack.clear();
return None;
}
self.stack.clear();
self.stack.push((0, u8::MAX));
if self.advance_next() { self.current() } else { None }
}
pub fn last(&mut self) -> Option<(&[u8], &mut V)> {
if self.trie.arena.is_empty() {
self.stack.clear();
return None;
}
self.stack.clear();
self.descend_last(0);
self.current()
}
#[inline]
pub fn next(&mut self) -> Option<(&[u8], &mut V)> {
if self.advance_next() { self.current() } else { None }
}
#[inline]
pub fn prev(&mut self) -> Option<(&[u8], &mut V)> {
if self.advance_prev() { self.current() } else { None }
}
#[inline]
pub fn next_index(&mut self) -> Option<usize> {
if self.advance_next() { self.current_index() } else { None }
}
#[inline]
pub fn prev_index(&mut self) -> Option<usize> {
if self.advance_prev() { self.current_index() } else { None }
}
pub fn seek(&mut self, key: &[u8]) -> Option<(&[u8], &mut V)> {
if self.trie.arena.is_empty() {
self.stack.clear();
return None;
}
self.stack.clear();
let mut node_idx: u32 = 0;
let mut prefix_len = self.trie.root_prefix_len as usize;
let max_bits = key.len() * 8;
loop {
let node = &self.trie.arena[node_idx as usize];
if prefix_len >= max_bits {
if node.is_terminal() {
self.stack.push((node_idx, TERMINAL_POS));
return self.current();
}
for bit in 0..2u8 {
if !node.is_empty(bit as usize) {
self.stack.push((node_idx, bit));
if node.is_leaf(bit as usize) {
return self.current();
} else {
self.descend_first(node.child_index(bit as usize));
return self.current();
}
}
}
return self.next();
}
let bit = key_bit_at(key, prefix_len) as usize;
let child = node.children[bit];
if child != 0 {
self.stack.push((node_idx, bit as u8));
if child & LEAF_BIT != 0 {
let ki = child & !LEAF_BIT;
let leaf_key = self.trie.keys.key_bytes(ki);
if leaf_key >= key {
return self.current();
}
return self.next();
} else {
prefix_len = node.prefix_lens[bit] as usize;
node_idx = child;
continue;
}
}
let other_bit = 1 - bit;
let other_child = node.children[other_bit];
if other_child != 0 && other_bit > bit {
self.stack.push((node_idx, other_bit as u8));
if other_child & LEAF_BIT != 0 {
return self.current();
} else {
self.descend_first(other_child);
return self.current();
}
}
if node.is_terminal() && bit == 0 {
let ki = node.leaf_key_index_val();
let term_key = self.trie.keys.key_bytes(ki);
if term_key >= key {
self.stack.push((node_idx, TERMINAL_POS));
return self.current();
}
}
loop {
let (parent_idx, parent_bit) = self.stack.pop()?;
if parent_bit == TERMINAL_POS || parent_bit == u8::MAX {
let parent = &self.trie.arena[parent_idx as usize];
for next_bit in 0..2u8 {
if !parent.is_empty(next_bit as usize) {
self.stack.push((parent_idx, next_bit));
if parent.is_leaf(next_bit as usize) {
return self.current();
} else {
self.descend_first(parent.child_index(next_bit as usize));
return self.current();
}
}
}
continue;
}
if parent_bit == 0 {
let parent = &self.trie.arena[parent_idx as usize];
if !parent.is_empty(1) {
self.stack.push((parent_idx, 1));
if parent.is_leaf(1) {
return self.current();
} else {
self.descend_first(parent.child_index(1));
return self.current();
}
}
}
}
}
}
}
#[cfg(test)]
#[path = "tests/bit_trie.rs"]
mod tests;