use crate::{
id::{PersyId, RecRef},
index::{
bytevec::ByteVec,
string_wrapper::StringWrapper,
tree::nodes::{Leaf, LeafEntry, Node, NodeRef, Nodes, Value},
},
io::{
ArcSliceRead, InfallibleRead, InfallibleReadFormat, InfallibleReadVarInt, InfallibleWrite,
InfallibleWriteFormat, InfallibleWriteVarInt,
},
};
pub trait IndexSerialization: Sized {
fn serialize(&self, buffer: &mut dyn InfallibleWrite);
fn deserialize(value: &mut dyn InfallibleRead) -> Self;
}
pub fn deserialize<K: IndexSerialization, V: IndexSerialization>(mut value: ArcSliceRead) -> Node<K, V> {
let version = value.read_u8();
match version {
0u8 => deserialize_v0(value),
_ => panic!("not compatible disc version"),
}
}
pub fn deserialize_v0<K: IndexSerialization, V: IndexSerialization>(mut reader: ArcSliceRead) -> Node<K, V> {
let t = reader.read_varint_u8();
match t {
1 => {
let prev = if reader.read_varint_u8() == 1 {
Some(K::deserialize(&mut reader))
} else {
None
};
let size = reader.read_varint_u32();
let mut entries = Vec::with_capacity(size as usize);
for _ in 0..size {
let key = K::deserialize(&mut reader);
let value_type = reader.read_varint_u8();
if value_type == 1 {
let val_size = reader.read_varint_u32();
let mut value = Vec::with_capacity(val_size as usize);
for _ in 0..val_size {
value.push(V::deserialize(&mut reader));
}
entries.push(LeafEntry {
key,
value: Value::Cluster(value),
});
} else {
let value = V::deserialize(&mut reader);
entries.push(LeafEntry {
key,
value: Value::Single(value),
});
}
}
let next = if reader.read_varint_u8() == 1 {
Some(K::deserialize(&mut reader))
} else {
None
};
Node::Leaf(Leaf { entries, prev, next })
}
2 => {
let prev = if reader.read_varint_u8() == 1 {
Some(K::deserialize(&mut reader))
} else {
None
};
let size = reader.read_varint_u32();
let mut keys = Vec::with_capacity(size as usize);
for _ in 0..size {
let key = K::deserialize(&mut reader);
keys.push(key);
}
let size = reader.read_varint_u32();
let mut pointers = Vec::with_capacity(size as usize);
for _ in 0..size {
let page = reader.read_varint_u64();
let pos = reader.read_varint_u32();
pointers.push(RecRef::new(page, pos));
}
let next = if reader.read_varint_u8() == 1 {
Some(K::deserialize(&mut reader))
} else {
None
};
Node::Node(Nodes {
keys,
pointers,
prev,
next,
})
}
_ => panic!("error on index node deserialization"),
}
}
pub fn serialize<K: IndexSerialization, V: IndexSerialization>(node: &Node<K, V>) -> Vec<u8> {
let mut dest = Vec::new();
dest.push(0u8);
serialize_v0(node, &mut dest);
dest
}
pub fn serialize_v0<K: IndexSerialization, V: IndexSerialization>(node: &Node<K, V>, dest: &mut dyn InfallibleWrite) {
let write_page_and_pos = |dest: &mut dyn InfallibleWrite, page, pos| {
dest.write_varint_u64(page);
dest.write_varint_u32(pos);
};
let write_opt_leafptr = |dest: &mut dyn InfallibleWrite, x: Option<&NodeRef>| {
if let Some(y) = x {
write_page_and_pos(dest, y.page, y.pos);
} else {
write_page_and_pos(dest, 0, 0);
}
};
match node {
Node::Leaf(leaf) => {
dest.write_varint_u8(1);
if let Some(pk) = &leaf.prev {
dest.write_varint_u8(1);
pk.serialize(dest);
} else {
dest.write_varint_u8(0);
}
dest.write_varint_u32(leaf.entries.len() as u32);
for entry in &leaf.entries {
entry.key.serialize(dest);
match &entry.value {
Value::Cluster(cluster) => {
dest.write_varint_u8(1);
dest.write_varint_u32(cluster.len() as u32);
for val in cluster {
val.serialize(dest);
}
}
Value::Single(val) => {
dest.write_varint_u8(2);
val.serialize(dest);
}
}
}
if let Some(pk) = &leaf.next {
dest.write_varint_u8(1);
pk.serialize(dest);
} else {
dest.write_varint_u8(0);
}
}
Node::Node(node) => {
dest.write_varint_u8(2);
if let Some(pk) = &node.prev {
dest.write_varint_u8(1);
pk.serialize(dest);
} else {
dest.write_varint_u8(0);
}
dest.write_varint_u32(node.keys.len() as u32);
for k in &node.keys {
k.serialize(dest);
}
dest.write_varint_u32(node.pointers.len() as u32);
for p in &node.pointers {
write_opt_leafptr(dest, Some(p));
}
if let Some(pk) = &node.next {
dest.write_varint_u8(1);
pk.serialize(dest);
} else {
dest.write_varint_u8(0);
}
}
}
}
impl IndexSerialization for u8 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u8(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_u8()
}
}
impl IndexSerialization for u16 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u16(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_u16()
}
}
impl IndexSerialization for u32 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u32(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_u32()
}
}
impl IndexSerialization for u64 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u64(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_u64()
}
}
impl IndexSerialization for u128 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u128(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_u128()
}
}
impl IndexSerialization for i8 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_i8(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_i8()
}
}
impl IndexSerialization for i16 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_i16(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_i16()
}
}
impl IndexSerialization for i32 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_i32(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_i32()
}
}
impl IndexSerialization for i64 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_i64(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_i64()
}
}
impl IndexSerialization for i128 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_i128(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_varint_i128()
}
}
impl IndexSerialization for f32 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_f32(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_f32()
}
}
impl IndexSerialization for f64 {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_f64(*self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
value.read_f64()
}
}
impl IndexSerialization for PersyId {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u64(self.0.page);
buffer.write_varint_u32(self.0.pos);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
let page = value.read_varint_u64();
let pos = value.read_varint_u32();
PersyId(RecRef::new(page, pos))
}
}
impl IndexSerialization for StringWrapper {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u32(self.len() as u32);
buffer.write_all(self.slice());
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
let vec_size = value.read_varint_u32();
value.read_slice(vec_size as usize).to_string_wrapper()
}
}
impl IndexSerialization for ByteVec {
fn serialize(&self, buffer: &mut dyn InfallibleWrite) {
buffer.write_varint_u32(self.len() as u32);
buffer.write_all(self);
}
fn deserialize(value: &mut dyn InfallibleRead) -> Self {
let vec_size = value.read_varint_u32();
value.read_slice(vec_size as usize).to_byte_vec()
}
}
#[cfg(test)]
mod tests {
use super::{deserialize, serialize};
use crate::id::{PersyId, RecRef};
use crate::index::{
bytevec::ByteVec,
config::{IndexTypeInternal, ValueMode},
string_wrapper::StringWrapper,
tree::nodes::{compare, Leaf, Node, NodeRef, Nodes, Value},
};
use crate::io::ArcSliceRead;
use rand::random;
use std::{cmp::Ordering, fmt::Debug, sync::Arc};
fn random_pointer() -> NodeRef {
RecRef::new(random::<u64>(), random::<u32>())
}
#[test]
fn test_serialization_deserialization_nodes() {
let val1 = random_pointer();
let val2 = random_pointer();
let val3 = random_pointer();
let mut node = Nodes::new_from_split(val1, &[(0, val2)]);
let pos = node.find(&2).pos;
node.add(pos, &2, val3.clone());
let value = serialize::<u8, u8>(&Node::Node(node));
let vl = value.len();
let read = deserialize::<u8, u8>(ArcSliceRead::new(Arc::new(value), 0, vl));
match read {
Node::Node(n) => {
assert_eq!(n.keys.len(), 2);
assert_eq!(n.pointers.len(), 3);
}
_ => panic!("expected a node"),
}
}
fn single_type_leaf_test<K: IndexTypeInternal + Debug, V: IndexTypeInternal + Debug>(key: K, value: V, value1: V) {
let mut leaf = Leaf::new();
leaf.insert_or_update(&key, &value, ValueMode::Replace, "deserialization error")
.expect("insert work");
let binary = serialize::<K, V>(&Node::Leaf(leaf));
let bl = binary.len();
let read = deserialize::<K, V>(ArcSliceRead::new(Arc::new(binary), 0, bl));
match read {
Node::Leaf(n) => {
assert_eq!(n.entries.len(), 1);
match n.entries[0].value {
Value::Single(ref iv) => assert_eq!(compare(iv, &value), Ordering::Equal),
_ => panic!("expected SINGLE"),
}
}
_ => panic!("expected a leaf"),
}
let mut leaf_many = Leaf::new();
leaf_many
.insert_or_update(&key, &value, ValueMode::Cluster, "deserialization error")
.expect("insert work");
leaf_many
.insert_or_update(&key, &value1, ValueMode::Cluster, "deserialization error")
.expect("insert work");
let binary = serialize::<K, V>(&Node::Leaf(leaf_many));
let bl = binary.len();
let read = deserialize::<K, V>(ArcSliceRead::new(Arc::new(binary), 0, bl));
match read {
Node::Leaf(n) => {
assert_eq!(n.entries.len(), 1);
match n.entries[0].value {
Value::Cluster(ref iv) => {
assert_eq!(compare(&iv[0], &value), Ordering::Equal);
assert_eq!(compare(&iv[1], &value1), Ordering::Equal);
}
_ => panic!("expected CLUSTER"),
}
}
_ => panic!("expected a leaf"),
}
}
#[test]
fn test_serialization_deserialization_leafs() {
single_type_leaf_test::<u8, u8>(20, 10, 20);
single_type_leaf_test::<u16, u16>(20, 10, 20);
single_type_leaf_test::<u32, u32>(20, 10, 20);
single_type_leaf_test::<u64, u64>(20, 10, 20);
single_type_leaf_test::<u128, u128>(20, 10, 20);
single_type_leaf_test::<i8, i8>(20, 10, 20);
single_type_leaf_test::<i16, i16>(20, 10, 20);
single_type_leaf_test::<i32, i32>(20, 10, 20);
single_type_leaf_test::<i64, i64>(20, 10, 20);
single_type_leaf_test::<i128, i128>(20, 10, 20);
single_type_leaf_test::<f32, f32>(20.0, 10.0, 20.0);
single_type_leaf_test::<f64, f64>(20.0, 10.0, 20.0);
single_type_leaf_test::<i32, StringWrapper>(
10,
StringWrapper::new("a".to_string()),
StringWrapper::new("b".to_string()),
);
single_type_leaf_test::<StringWrapper, i32>(StringWrapper::new("a".to_string()), 10, 20);
single_type_leaf_test::<StringWrapper, ByteVec>(
StringWrapper::new("a".to_string()),
vec![0, 1].into(),
vec![2, 10].into(),
);
single_type_leaf_test::<ByteVec, ByteVec>(vec![11, 12].into(), vec![0, 1].into(), vec![2, 10].into());
single_type_leaf_test::<StringWrapper, StringWrapper>(
StringWrapper::new("o".to_string()),
StringWrapper::new("a".to_string()),
StringWrapper::new("b".to_string()),
);
let id = PersyId(RecRef::new(10, 20));
let id1 = PersyId(RecRef::new(20, 20));
let id2 = PersyId(RecRef::new(30, 20));
single_type_leaf_test::<PersyId, PersyId>(id, id1, id2);
}
}