pub trait TrieKey: Default {
type Store: KeyStore<Self>;
fn as_bytes(&self) -> &[u8];
}
pub trait KeyStore<K>: Default {
fn push(&mut self, key: K) -> u32;
fn key_bytes(&self, ki: u32) -> &[u8];
fn rollback(&mut self);
fn len(&self) -> usize;
fn into_keys(self) -> Vec<K>;
}
pub struct BufKeyStore {
buf: Vec<u8>,
index: Vec<(usize, u16)>,
}
impl Default for BufKeyStore {
fn default() -> Self {
BufKeyStore {
buf: Vec::new(),
index: vec![(0, 0)], }
}
}
impl KeyStore<Vec<u8>> for BufKeyStore {
fn push(&mut self, key: Vec<u8>) -> u32 {
let ki = self.index.len() as u32;
let offset = self.buf.len();
debug_assert!(key.len() <= u16::MAX as usize, "BufKeyStore key length exceeds u16::MAX");
self.buf.extend_from_slice(&key);
self.index.push((offset, key.len() as u16));
ki
}
fn key_bytes(&self, ki: u32) -> &[u8] {
let (off, len) = self.index[ki as usize];
&self.buf[off..off + len as usize]
}
fn rollback(&mut self) {
let (off, _len) = self.index.pop().unwrap();
self.buf.truncate(off);
}
fn len(&self) -> usize {
self.index.len() - 1
}
fn into_keys(self) -> Vec<Vec<u8>> {
let buf = self.buf;
self.index
.into_iter()
.skip(1)
.map(|(off, len)| buf[off..off + len as usize].to_vec())
.collect()
}
}
pub struct VecKeyStore<K: TrieKey> {
keys: Vec<K>, }
impl<K: TrieKey> Default for VecKeyStore<K> {
fn default() -> Self {
VecKeyStore {
keys: vec![K::default()], }
}
}
impl<K: TrieKey> KeyStore<K> for VecKeyStore<K> {
fn push(&mut self, key: K) -> u32 {
let ki = self.keys.len() as u32;
self.keys.push(key);
ki
}
fn key_bytes(&self, ki: u32) -> &[u8] {
self.keys[ki as usize].as_bytes()
}
fn rollback(&mut self) {
self.keys.pop();
}
fn len(&self) -> usize {
self.keys.len() - 1
}
fn into_keys(self) -> Vec<K> {
self.keys.into_iter().skip(1).collect()
}
}
pub trait ByteKey: TrieKey {
type Borrowed<'a>: AsRef<[u8]> + 'a
where
Self: 'a;
fn bytes(&self) -> &[u8];
fn from_bytes(bytes: &[u8]) -> Self;
fn as_borrowed<'a>(bytes: &'a [u8]) -> Self::Borrowed<'a>;
}
impl ByteKey for Vec<u8> {
type Borrowed<'a> = &'a [u8] where Self: 'a;
fn bytes(&self) -> &[u8] {
self
}
fn from_bytes(bytes: &[u8]) -> Self {
bytes.to_vec()
}
fn as_borrowed<'a>(bytes: &'a [u8]) -> &'a [u8] {
bytes
}
}
impl ByteKey for String {
type Borrowed<'a> = &'a str where Self: 'a;
fn bytes(&self) -> &[u8] {
self.as_bytes()
}
fn from_bytes(bytes: &[u8]) -> Self {
String::from_utf8(bytes.to_vec()).unwrap()
}
fn as_borrowed<'a>(bytes: &'a [u8]) -> &'a str {
unsafe { std::str::from_utf8_unchecked(bytes) }
}
}
impl TrieKey for Vec<u8> {
type Store = BufKeyStore;
fn as_bytes(&self) -> &[u8] {
self
}
}
impl TrieKey for String {
type Store = VecKeyStore<String>;
fn as_bytes(&self) -> &[u8] {
self.as_bytes()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn buf_store_push_and_key_bytes() {
let mut store = BufKeyStore::default();
assert_eq!(store.len(), 0);
let ki1 = store.push(b"hello".to_vec());
assert_eq!(ki1, 1);
assert_eq!(store.key_bytes(1), b"hello");
assert_eq!(store.len(), 1);
let ki2 = store.push(b"world".to_vec());
assert_eq!(ki2, 2);
assert_eq!(store.key_bytes(2), b"world");
assert_eq!(store.len(), 2);
}
#[test]
fn buf_store_rollback() {
let mut store = BufKeyStore::default();
store.push(b"hello".to_vec());
store.push(b"world".to_vec());
assert_eq!(store.len(), 2);
store.rollback();
assert_eq!(store.len(), 1);
assert_eq!(store.key_bytes(1), b"hello");
}
#[test]
fn buf_store_into_keys() {
let mut store = BufKeyStore::default();
store.push(b"abc".to_vec());
store.push(b"def".to_vec());
let keys = store.into_keys();
assert_eq!(keys, vec![b"abc".to_vec(), b"def".to_vec()]);
}
#[test]
fn buf_store_empty_key() {
let mut store = BufKeyStore::default();
let ki = store.push(b"".to_vec());
assert_eq!(ki, 1);
assert_eq!(store.key_bytes(1), b"");
}
#[test]
fn buf_store_dummy_entry() {
let store = BufKeyStore::default();
assert_eq!(store.key_bytes(0), b"");
}
#[test]
fn vec_store_push_and_key_bytes() {
let mut store = VecKeyStore::<String>::default();
assert_eq!(store.len(), 0);
let ki1 = store.push("hello".to_string());
assert_eq!(ki1, 1);
assert_eq!(store.key_bytes(1), b"hello");
assert_eq!(store.len(), 1);
let ki2 = store.push("world".to_string());
assert_eq!(ki2, 2);
assert_eq!(store.key_bytes(2), b"world");
}
#[test]
fn vec_store_rollback() {
let mut store = VecKeyStore::<String>::default();
store.push("hello".to_string());
store.push("world".to_string());
store.rollback();
assert_eq!(store.len(), 1);
assert_eq!(store.key_bytes(1), b"hello");
}
#[test]
fn vec_store_into_keys() {
let mut store = VecKeyStore::<String>::default();
store.push("abc".to_string());
store.push("def".to_string());
let keys = store.into_keys();
assert_eq!(keys, vec!["abc".to_string(), "def".to_string()]);
}
#[test]
fn vec_store_dummy_entry() {
let store = VecKeyStore::<String>::default();
assert_eq!(store.key_bytes(0), b"");
}
}