#![feature(test, specialization)]
use std::{cmp, cmp::Ordering, iter};
pub mod bits;
pub mod bitter;
use self::bits::*;
use self::bitter::*;
macro_rules! guard {
($e:expr) => {
if !$e {
return None;
}
};
}
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct Node {
loc: Vec<u64>, key: Vec<u8>, }
impl Ord for Node {
fn cmp(&self, other: &Node) -> Ordering {
match self.loc.cmp(&other.loc) {
Ordering::Equal => self.key.cmp(&other.key),
o => o,
}
}
}
impl PartialOrd for Node {
fn partial_cmp(&self, other: &Node) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<A: AsRef<[u64]>> From<A> for Node {
default fn from(loc: A) -> Self {
assert!(!loc.as_ref().contains(&0));
Node {
loc: loc.as_ref().to_vec(),
key: Vec::new(),
}
}
}
impl From<Vec<u64>> for Node {
fn from(loc: Vec<u64>) -> Self {
Self::from_vec(loc)
}
}
impl AsRef<[u8]> for Node {
fn as_ref(&self) -> &[u8] {
&self.key
}
}
impl Node {
pub fn root() -> Self {
Self::default()
}
pub fn position(&self) -> &[u64] {
&self.loc
}
pub fn key(&self) -> &[u8] {
&self.key
}
pub fn from_vec(loc: Vec<u64>) -> Self {
Self::from_vec_parts(loc, Vec::new())
}
pub fn from_parts<A: AsRef<[u64]>, B: AsRef<[u8]>>(loc: A, key: B) -> Self {
assert!(!loc.as_ref().contains(&0));
Node {
loc: loc.as_ref().to_vec(),
key: key.as_ref().to_vec(),
}
}
pub fn from_vec_parts(loc: Vec<u64>, key: Vec<u8>) -> Self {
assert!(!loc.contains(&0));
Node { loc, key }
}
pub fn with_key<K: AsRef<[u8]>>(&self, key: K) -> Self {
Node {
loc: self.loc.clone(),
key: key.as_ref().to_vec(),
}
}
pub fn with_vec_key(&self, key: Vec<u8>) -> Self {
Node {
loc: self.loc.clone(),
key,
}
}
pub fn set_key<K: AsRef<[u8]>>(&mut self, key: K) {
self.key = key.as_ref().to_vec();
}
pub fn set_vec_key(&mut self, key: Vec<u8>) {
self.key = key
}
pub fn parent(&self) -> Self {
let mut parent = self.clone();
parent.parent_mut();
parent
}
pub fn parent_mut(&mut self) {
self.loc.pop();
}
pub fn child(&self, id: u64) -> Self {
let mut child = self.clone();
child.child_mut(id);
child
}
pub fn child_mut(&mut self, id: u64) {
assert!(id != 0);
self.loc.push(id);
}
pub fn sibling(&self, id: u64) -> Option<Self> {
guard! { !self.is_root() };
let mut sibling = self.clone();
sibling.sibling_mut(id);
Some(sibling)
}
pub fn sibling_mut(&mut self, id: u64) {
assert!(id != 0);
if let Some(c) = self.loc.last_mut() {
*c = id;
}
}
pub fn pred(&self) -> Option<Self> {
let mut pred = self.clone();
let x = pred.loc.last_mut()?;
guard! { *x >= 2 };
*x -= 1;
Some(pred)
}
pub fn succ(&self) -> Option<Self> {
let mut succ = self.clone();
(*succ.loc.last_mut()?) += 1;
Some(succ)
}
pub fn is_root(&self) -> bool {
self.loc.is_empty()
}
pub fn from_binary<A: AsRef<[u8]>>(mlcf_encoded: A) -> Option<Self> {
let mut loc: Vec<u64> = Vec::new();
let mut it = mlcf_encoded.as_ref().iter().peekable();
if Some(&&0) == it.peek() {
guard! { it.next()? == &0 }; let key = it.cloned().collect(); return Some(Self::from_vec_parts(loc, key));
}
let mut cursor: u8 = 0;
'chunker: loop {
let mut nz_tot: u8 = 0;
'prefixer: while let Some(&&seg) = it.peek() {
let nz = (!(seg << cursor)).leading_zeros();
nz_tot += nz as u8;
if rotate_consume(&mut it, &mut cursor, nz as u8)? {
continue 'prefixer;
}
guard! { !kth_bit(seg, cursor) };
break 'prefixer;
}
rotate_incr(&mut it, &mut cursor)?;
let mut term: u64 = 1;
'payloader: while let Some(&&seg) = it.peek() {
let until_end = U8_WIDTH - cursor;
let mut data_mask = (seg << cursor) >> cursor;
data_mask >>= until_end.saturating_sub(nz_tot);
let safe_bits = cmp::min(nz_tot, until_end);
term <<= safe_bits;
term |= u64::from(data_mask);
nz_tot -= safe_bits;
rotate_consume(&mut it, &mut cursor, safe_bits)?;
if nz_tot == 0 {
break 'payloader;
}
}
loc.push(term);
if !kth_bit_iter(&mut it, cursor) {
it.next()?;
break 'chunker;
}
rotate_incr(&mut it, &mut cursor)?;
}
guard! { it.next()? == &0 }; let key = it.cloned().collect();
Some(Self::from_vec_parts(loc, key))
}
pub fn to_binary(&self) -> Vec<u8> {
let evens = self.loc.iter();
let odds = iter::repeat(&1).take(self.loc.len().saturating_sub(1));
let it = itertools::interleave(evens, odds);
let mut stack = BitWriter::with_capacity(self.key.len() + self.loc.len());
for (i, &x) in it.enumerate() {
if i % 2 != 0 {
stack.push_bit(true);
continue;
}
let nz = x.leading_zeros() as u8;
let nd = 63u8.saturating_sub(nz);
stack.push_bits(std::u64::MAX, nd);
stack.push_bit(false);
stack.push_bits(x, nd);
}
stack.align();
stack.push(0x00);
stack.push_bytes(&self.key);
stack.into_vec()
}
}
#[cfg(test)]
mod tests {
extern crate rand;
extern crate test;
use self::test::Bencher;
use super::*;
use num_bigint::BigUint;
use num_rational::Ratio;
impl Node {
fn as_ratio(&self) -> Ratio<BigUint> {
let ex = &self.cf_expansion();
let one = Ratio::new(BigUint::from(1usize), BigUint::from(1usize));
let mut last = Ratio::from_integer(BigUint::from(0usize));
for i in (0..ex.len()).rev() {
let term = &one / (Ratio::new(BigUint::from(ex[i]), BigUint::from(1usize)) + last);
last = term;
}
last.recip()
}
fn cf_expansion(&self) -> Vec<u64> {
let evens = self.loc.iter();
let odds = iter::repeat(&1).take(self.loc.len() - 1);
itertools::interleave(evens, odds).cloned().collect()
}
}
#[test]
fn child_parent_eq() {
let b = Node::from(&[1, 2, 3]);
assert_eq!(b, b.child(4).parent());
}
#[bench]
fn binary_lo_2(b: &mut Bencher) {
let v: Vec<u64> = (1..=2).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_lo_4(b: &mut Bencher) {
let v: Vec<u64> = (1..=4).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_lo_8(b: &mut Bencher) {
let v: Vec<u64> = (1..=8).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_lo_16(b: &mut Bencher) {
let v: Vec<u64> = (1..=16).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_lo_32(b: &mut Bencher) {
let v: Vec<u64> = (1..=32).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_lo_64(b: &mut Bencher) {
let v: Vec<u64> = (1..=64).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_hi_2(b: &mut Bencher) {
let v: Vec<u64> = (1..=2).map(|_| rand::random()).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_hi_4(b: &mut Bencher) {
let v: Vec<u64> = (1..=4).map(|_| rand::random()).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_hi_8(b: &mut Bencher) {
let v: Vec<u64> = (1..=8).map(|_| rand::random()).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_hi_16(b: &mut Bencher) {
let v: Vec<u64> = (1..=16).map(|_| rand::random()).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_hi_32(b: &mut Bencher) {
let v: Vec<u64> = (1..=32).map(|_| rand::random()).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[bench]
fn binary_hi_64(b: &mut Bencher) {
let v: Vec<u64> = (1..=64).map(|_| rand::random()).collect();
let node = Node::from(&v);
b.iter(|| Node::from_binary(&*node.to_binary()).unwrap());
}
#[test]
fn edge_case() {
let n1 = Node::from(&[2, 4, 1]); let n2 = Node::from(&[2, 5]); println!("2 . 4 . 1 : {:?}", Node::from_binary(&*n1.to_binary()),);
println!();
println!("2 . 5 : {:?}", Node::from_binary(&*n2.to_binary()),);
println!();
assert!(n1 < n2);
assert!(n1.as_ratio() < n2.as_ratio());
assert!(n1.to_binary() < n2.to_binary());
}
struct BfsIter {
stack: BigUint,
radix: u32,
}
impl BfsIter {
fn new(rdx: u32) -> BfsIter {
BfsIter {
stack: BigUint::new(vec![]),
radix: rdx,
}
}
}
impl Iterator for BfsIter {
type Item = Vec<u64>;
fn next(&mut self) -> Option<Self::Item> {
let item = self
.stack
.to_radix_le(self.radix)
.iter()
.map(|&x| u64::from(x + 1))
.collect();
self.stack += BigUint::from(1u8);
Some(item)
}
}
#[test]
fn bfs_iter_round_trip() {
let mut it = BfsIter::new(15);
it.next().unwrap();
for i in 0..2u64.pow(14) {
let v = it.next().unwrap();
println!("raw input is: {:?}", v);
let nd = Node::from_vec_parts(v, (1..=24).map(|_| rand::random()).collect());
println!("roundtripping: #{} {:?}", i, nd);
let bin = nd.to_binary();
println!("binary: {:?}", bin);
assert_eq!(nd, Node::from_binary(&*bin).unwrap());
}
}
#[test]
fn lcf_enc() {
let mut node = Node::from_parts(&[1], b"hello worldo");
let mut last = node.clone();
for i in 0..250 {
node.set_vec_key((1..=48).map(|_| rand::random()).collect());
node = node.succ().unwrap();
if i % 100 == 0 {
node.child_mut(rand::random());
}
assert!(last < node);
assert!(last.as_ratio() < node.as_ratio());
assert!(last.to_binary() < node.to_binary());
last = node.clone();
}
while !node.loc.is_empty() {
node.set_vec_key((1..=48).map(|_| rand::random()).collect());
for _ in 0..16 {
node.set_vec_key((1..=48).map(|_| rand::random()).collect());
node = node.succ().unwrap();
assert!(last < node);
assert!(last.as_ratio() < node.as_ratio());
assert!(last.to_binary() < node.to_binary());
last = node.clone();
}
node.parent_mut();
}
}
}