pub const ORDER_KEY_MAX: usize = 4096;
pub const END_LEN: usize = 8;
pub const SEQ_MIN: i64 = -(1 << 55);
pub const SEQ_MAX: i64 = (1 << 55) - 1;
const MID: u8 = 0x80;
const SEQ_MASK: u64 = (1u64 << 56) - 1;
#[must_use]
pub fn end(seq: i64) -> [u8; END_LEN] {
assert!(
(SEQ_MIN..=SEQ_MAX).contains(&seq),
"list order sequence out of range"
);
let u = (((seq as u64) ^ (1u64 << 55)) & SEQ_MASK) << 8;
let mut key = u.to_be_bytes();
key[END_LEN - 1] = MID;
key
}
#[must_use]
pub fn seq_of(key: &[u8]) -> Option<i64> {
if key.len() != END_LEN || key[END_LEN - 1] != MID {
return None;
}
let mut bytes = [0u8; END_LEN];
bytes.copy_from_slice(key);
bytes[END_LEN - 1] = 0;
let v = (u64::from_be_bytes(bytes) >> 8) ^ (1u64 << 55);
Some(((v << 8) as i64) >> 8)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Ends {
front: i64,
back: i64,
}
impl Default for Ends {
fn default() -> Ends {
Ends::new()
}
}
impl Ends {
#[must_use]
pub fn new() -> Ends {
Ends { front: -1, back: 0 }
}
pub fn push_front(&mut self) -> Option<[u8; END_LEN]> {
if self.front < SEQ_MIN {
return None;
}
let key = end(self.front);
self.front -= 1;
Some(key)
}
pub fn push_back(&mut self) -> Option<[u8; END_LEN]> {
if self.back > SEQ_MAX {
return None;
}
let key = end(self.back);
self.back += 1;
Some(key)
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum Descent {
Both,
Upper,
Lower,
}
pub fn between(lo: &[u8], hi: &[u8], out: &mut [u8]) -> Option<usize> {
if lo >= hi {
return None;
}
let cap = out.len().min(ORDER_KEY_MAX);
let mut mode = Descent::Both;
let mut i = 0;
let len = loop {
if i >= cap {
return None;
}
match mode {
Descent::Both => {
let h = *hi.get(i)?;
match lo.get(i) {
None => mode = Descent::Upper,
Some(&l) if h - l >= 2 => {
out[i] = l + (h - l) / 2;
break i + 1;
}
Some(&l) if h - l == 1 => {
out[i] = l;
i += 1;
mode = Descent::Lower;
}
Some(&l) => {
out[i] = l;
i += 1;
}
}
}
Descent::Upper => {
let h = *hi.get(i)?;
if h == 0 {
out[i] = 0;
i += 1;
} else {
out[i] = h / 2;
break i + 1;
}
}
Descent::Lower => {
match lo.get(i) {
Some(&0xff) => {
out[i] = 0xff;
i += 1;
}
Some(&l) => {
out[i] = l + 1 + (0xff - l) / 2;
break i + 1;
}
None => {
out[i] = MID;
break i + 1;
}
}
}
}
};
if out[len - 1] == 0 {
if len >= cap {
return None;
}
out[len] = MID;
return Some(len + 1);
}
Some(len)
}
#[cfg(test)]
mod tests {
use super::*;
fn buf() -> [u8; ORDER_KEY_MAX] {
[0u8; ORDER_KEY_MAX]
}
#[test]
fn an_end_key_sorts_the_way_the_sequence_does() {
let seqs = [
SEQ_MIN,
SEQ_MIN + 1,
-1_000_000,
-256,
-1,
0,
1,
255,
256,
1_000_000,
SEQ_MAX - 1,
SEQ_MAX,
];
for pair in seqs.windows(2) {
let (a, b) = (end(pair[0]), end(pair[1]));
assert!(a < b, "{:?} should sort under {:?}", pair[0], pair[1]);
}
for seq in seqs {
let key = end(seq);
assert_eq!(seq_of(&key), Some(seq));
assert_ne!(key[END_LEN - 1], 0, "an end key must not end in a zero");
}
}
#[test]
fn a_key_that_did_not_come_from_end_is_not_read_as_one() {
assert_eq!(seq_of(b""), None);
assert_eq!(seq_of(b"1234567"), None);
assert_eq!(seq_of(b"123456789"), None);
assert_eq!(seq_of(&[0x80, 0, 0, 0, 0, 0, 0, 0x40]), None);
}
#[test]
fn the_ends_only_ever_move_outward() {
let mut ends = Ends::new();
let a = ends.push_back().unwrap();
let b = ends.push_back().unwrap();
let x = ends.push_front().unwrap();
let y = ends.push_front().unwrap();
assert!(y < x && x < a && a < b);
let c = ends.push_back().unwrap();
assert!(b < c);
}
#[test]
fn a_key_between_two_lands_between_them() {
let mut out = buf();
let cases: &[(&[u8], &[u8])] = &[
(b"a", b"c"),
(b"a", b"b"),
(b"aa", b"ab"),
(b"a", b"aa"),
(&[0x00], &[0xff]),
(&[0x41], &[0x41, 0x01, 0x80]),
(&[0xff, 0xff, 0x80], &[0xff, 0xff, 0x81]),
(&end(0), &end(1)),
(&end(-1), &end(0)),
(&end(SEQ_MIN), &end(SEQ_MAX)),
];
for &(lo, hi) in cases {
let n = between(lo, hi, &mut out).expect("there is room between these");
let key = &out[..n];
assert!(lo < key, "{key:?} should sort above {lo:?}");
assert!(key < hi, "{key:?} should sort under {hi:?}");
assert_ne!(key[n - 1], 0, "{key:?} must not end in a zero");
}
}
#[test]
fn there_is_nothing_between_a_key_and_itself_or_a_pair_the_wrong_way_round() {
let mut out = buf();
assert_eq!(between(b"a", b"a", &mut out), None);
assert_eq!(between(b"b", b"a", &mut out), None);
assert_eq!(between(b"aa", b"a", &mut out), None);
assert_eq!(between(b"a", b"a\x00", &mut out), None);
assert_eq!(between(b"a", b"a\x00\x00", &mut out), None);
}
#[test]
fn a_key_that_will_not_fit_is_refused_rather_than_truncated() {
let mut small = [0u8; 2];
assert_eq!(between(&end(0), &end(1), &mut small), None);
let mut one = [0u8; 1];
assert_eq!(between(b"a", b"c", &mut one), Some(1));
assert_eq!(one[0], b'b');
}
#[test]
fn every_pair_that_honours_the_invariant_has_a_key_between_it() {
let alphabet = [0x00u8, 0x01, 0x02, 0x7f, 0x80, 0xfe, 0xff];
let mut keys: Vec<Vec<u8>> = Vec::new();
for len in 1..=3 {
let mut key = vec![0u8; len];
let mut counter = 0usize;
let total = alphabet.len().pow(u32::try_from(len).unwrap());
while counter < total {
let mut n = counter;
for byte in key.iter_mut().take(len) {
*byte = alphabet[n % alphabet.len()];
n /= alphabet.len();
}
if key[len - 1] != 0 {
keys.push(key.clone());
}
counter += 1;
}
}
keys.sort();
let mut out = buf();
let mut pairs = 0;
for (i, lo) in keys.iter().enumerate() {
for hi in &keys[i + 1..] {
let n = between(lo, hi, &mut out).expect("the invariant leaves room");
let key = &out[..n];
assert!(lo.as_slice() < key, "{key:?} above {lo:?}");
assert!(key < hi.as_slice(), "{key:?} under {hi:?}");
assert_ne!(key[n - 1], 0);
pairs += 1;
}
}
assert_eq!(pairs, 58_311, "every ordered pair of the 342 legal keys");
}
#[test]
fn a_hammer_at_one_spot_grows_by_a_byte_every_eight_inserts() {
const N: usize = 20_000;
let lo = end(0);
let mut hi = end(1).to_vec();
let mut out = buf();
let mut deepest = 0;
for i in 0..N {
let n = between(&lo, &hi, &mut out)
.unwrap_or_else(|| panic!("wedged after {i} inserts, which is what scheme A does"));
let key = &out[..n];
assert!(lo.as_slice() < key && key < hi.as_slice());
assert_ne!(key[n - 1], 0);
deepest = deepest.max(n);
hi.clear();
hi.extend_from_slice(key);
}
let grown = deepest - END_LEN;
let per_byte = N as f64 / grown as f64;
assert!(
per_byte >= 8.0,
"{per_byte} inserts per byte, K14 asks for 8.0"
);
assert_eq!(deepest, 2508, "aki's number, to the byte");
}
#[test]
fn a_hammer_under_the_upper_neighbour_grows_at_the_same_rate() {
const N: usize = 20_000;
let hi = end(1);
let mut lo = end(0).to_vec();
let mut out = buf();
let mut deepest = 0;
for _ in 0..N {
let n = between(&lo, &hi, &mut out).expect("a variable key does not wedge");
let key = &out[..n];
assert!(lo.as_slice() < key && key < hi.as_slice());
assert_ne!(key[n - 1], 0);
deepest = deepest.max(n);
lo.clear();
lo.extend_from_slice(key);
}
let per_byte = N as f64 / (deepest - END_LEN) as f64;
assert!(
per_byte >= 8.0,
"{per_byte} inserts per byte, K14 asks for 8.0"
);
}
#[test]
fn a_list_built_only_out_of_its_own_keys_stays_ordered() {
let mut keys: Vec<Vec<u8>> = vec![end(0).to_vec(), end(1).to_vec()];
let mut out = buf();
let mut seed = 0x2545_f491_4f6c_dd1du64;
for _ in 0..5_000 {
seed ^= seed << 13;
seed ^= seed >> 7;
seed ^= seed << 17;
let at = (seed % (keys.len() as u64 - 1)) as usize;
let n = between(&keys[at], &keys[at + 1], &mut out).expect("no wedge");
keys.insert(at + 1, out[..n].to_vec());
}
assert!(keys.windows(2).all(|w| w[0] < w[1]), "the list is ordered");
assert!(keys.iter().all(|k| *k.last().unwrap() != 0), "invariant");
assert_eq!(keys.len(), 5_002);
}
}