mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 21:07:43 +00:00
Refine the new encoding schema (#244)
* perf: refine the new encoding schema * chore: rm auto derived fromprimitive and toprimitive from encode mode
This commit is contained in:
parent
5f1353791d
commit
b8cf4dc4c3
3 changed files with 145 additions and 10 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -10,6 +10,7 @@
|
|||
"heapless",
|
||||
"idspan",
|
||||
"insta",
|
||||
"Itertools",
|
||||
"Leeeon",
|
||||
"LOGSTORE",
|
||||
"napi",
|
||||
|
|
|
@ -4,12 +4,11 @@ use crate::op::OpWithId;
|
|||
use crate::LoroDoc;
|
||||
use crate::{oplog::OpLog, LoroError, VersionVector};
|
||||
use loro_common::{HasCounter, IdSpan, LoroResult};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use rle::{HasLength, Sliceable};
|
||||
const MAGIC_BYTES: [u8; 4] = *b"loro";
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum EncodeMode {
|
||||
// This is a config option, it won't be used in encoding.
|
||||
Auto = 255,
|
||||
|
@ -17,6 +16,42 @@ pub(crate) enum EncodeMode {
|
|||
Snapshot = 2,
|
||||
}
|
||||
|
||||
impl num_traits::FromPrimitive for EncodeMode {
|
||||
#[allow(trivial_numeric_casts)]
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
if n == EncodeMode::Auto as i64 {
|
||||
Some(EncodeMode::Auto)
|
||||
} else if n == EncodeMode::Rle as i64 {
|
||||
Some(EncodeMode::Rle)
|
||||
} else if n == EncodeMode::Snapshot as i64 {
|
||||
Some(EncodeMode::Snapshot)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
Self::from_i64(n as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl num_traits::ToPrimitive for EncodeMode {
|
||||
#[inline]
|
||||
#[allow(trivial_numeric_casts)]
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
Some(match *self {
|
||||
EncodeMode::Auto => EncodeMode::Auto as i64,
|
||||
EncodeMode::Rle => EncodeMode::Rle as i64,
|
||||
EncodeMode::Snapshot => EncodeMode::Snapshot as i64,
|
||||
})
|
||||
}
|
||||
#[inline]
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
self.to_i64().map(|x| x as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl EncodeMode {
|
||||
pub fn to_bytes(self) -> [u8; 2] {
|
||||
let value = self.to_u16().unwrap();
|
||||
|
|
|
@ -1220,7 +1220,7 @@ struct EncodedOp {
|
|||
container_index: u32,
|
||||
#[columnar(strategy = "DeltaRle")]
|
||||
prop: i32,
|
||||
#[columnar(strategy = "Rle")]
|
||||
#[columnar(strategy = "DeltaRle")]
|
||||
peer_idx: u32,
|
||||
#[columnar(strategy = "DeltaRle")]
|
||||
value_type: u8,
|
||||
|
@ -1231,7 +1231,7 @@ struct EncodedOp {
|
|||
#[columnar(vec, ser, de, iterable)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct EncodedChange {
|
||||
#[columnar(strategy = "Rle")]
|
||||
#[columnar(strategy = "DeltaRle")]
|
||||
peer_idx: usize,
|
||||
#[columnar(strategy = "DeltaRle")]
|
||||
len: usize,
|
||||
|
@ -1263,12 +1263,10 @@ mod value {
|
|||
use loro_common::{
|
||||
ContainerID, Counter, InternalString, LoroError, LoroResult, LoroValue, PeerID, TreeID,
|
||||
};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
|
||||
use crate::container::tree::tree_op::TreeOp;
|
||||
|
||||
use super::{encode::ValueRegister, MAX_COLLECTION_SIZE};
|
||||
use crate::container::tree::tree_op::TreeOp;
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
|
||||
#[allow(unused)]
|
||||
#[non_exhaustive]
|
||||
|
@ -1339,8 +1337,7 @@ mod value {
|
|||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, FromPrimitive, ToPrimitive)]
|
||||
#[derive(Debug)]
|
||||
pub enum ValueKind {
|
||||
Null = 0,
|
||||
True = 1,
|
||||
|
@ -1360,6 +1357,108 @@ mod value {
|
|||
Unknown = 65536,
|
||||
}
|
||||
|
||||
impl num_traits::FromPrimitive for ValueKind {
|
||||
#[allow(trivial_numeric_casts)]
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
if n == ValueKind::Null as u8 {
|
||||
Some(ValueKind::Null)
|
||||
} else if n == ValueKind::True as u8 {
|
||||
Some(ValueKind::True)
|
||||
} else if n == ValueKind::False as u8 {
|
||||
Some(ValueKind::False)
|
||||
} else if n == ValueKind::DeleteOnce as u8 {
|
||||
Some(ValueKind::DeleteOnce)
|
||||
} else if n == ValueKind::I32 as u8 {
|
||||
Some(ValueKind::I32)
|
||||
} else if n == ValueKind::ContainerIdx as u8 {
|
||||
Some(ValueKind::ContainerIdx)
|
||||
} else if n == ValueKind::F64 as u8 {
|
||||
Some(ValueKind::F64)
|
||||
} else if n == ValueKind::Str as u8 {
|
||||
Some(ValueKind::Str)
|
||||
} else if n == ValueKind::DeleteSeq as u8 {
|
||||
Some(ValueKind::DeleteSeq)
|
||||
} else if n == ValueKind::DeltaInt as u8 {
|
||||
Some(ValueKind::DeltaInt)
|
||||
} else if n == ValueKind::Array as u8 {
|
||||
Some(ValueKind::Array)
|
||||
} else if n == ValueKind::Map as u8 {
|
||||
Some(ValueKind::Map)
|
||||
} else if n == ValueKind::MarkStart as u8 {
|
||||
Some(ValueKind::MarkStart)
|
||||
} else if n == ValueKind::TreeMove as u8 {
|
||||
Some(ValueKind::TreeMove)
|
||||
} else if n == ValueKind::Binary as u8 {
|
||||
Some(ValueKind::Binary)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
Self::from_u8(n as u8)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
Self::from_u8(n as u8)
|
||||
}
|
||||
}
|
||||
|
||||
impl num_traits::ToPrimitive for ValueKind {
|
||||
#[inline]
|
||||
#[allow(trivial_numeric_casts)]
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
Some(match *self {
|
||||
ValueKind::Null => ValueKind::Null as i64,
|
||||
ValueKind::True => ValueKind::True as i64,
|
||||
ValueKind::False => ValueKind::False as i64,
|
||||
ValueKind::DeleteOnce => ValueKind::DeleteOnce as i64,
|
||||
ValueKind::I32 => ValueKind::I32 as i64,
|
||||
ValueKind::ContainerIdx => ValueKind::ContainerIdx as i64,
|
||||
ValueKind::F64 => ValueKind::F64 as i64,
|
||||
ValueKind::Str => ValueKind::Str as i64,
|
||||
ValueKind::DeleteSeq => ValueKind::DeleteSeq as i64,
|
||||
ValueKind::DeltaInt => ValueKind::DeltaInt as i64,
|
||||
ValueKind::Array => ValueKind::Array as i64,
|
||||
ValueKind::Map => ValueKind::Map as i64,
|
||||
ValueKind::MarkStart => ValueKind::MarkStart as i64,
|
||||
ValueKind::TreeMove => ValueKind::TreeMove as i64,
|
||||
ValueKind::Binary => ValueKind::Binary as i64,
|
||||
ValueKind::Unknown => ValueKind::Unknown as i64,
|
||||
})
|
||||
}
|
||||
#[inline]
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
self.to_i64().map(|x| x as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(trivial_numeric_casts)]
|
||||
fn to_u8(&self) -> Option<u8> {
|
||||
Some(match *self {
|
||||
ValueKind::Null => ValueKind::Null as u8,
|
||||
ValueKind::True => ValueKind::True as u8,
|
||||
ValueKind::False => ValueKind::False as u8,
|
||||
ValueKind::DeleteOnce => ValueKind::DeleteOnce as u8,
|
||||
ValueKind::I32 => ValueKind::I32 as u8,
|
||||
ValueKind::ContainerIdx => ValueKind::ContainerIdx as u8,
|
||||
ValueKind::F64 => ValueKind::F64 as u8,
|
||||
ValueKind::Str => ValueKind::Str as u8,
|
||||
ValueKind::DeleteSeq => ValueKind::DeleteSeq as u8,
|
||||
ValueKind::DeltaInt => ValueKind::DeltaInt as u8,
|
||||
ValueKind::Array => ValueKind::Array as u8,
|
||||
ValueKind::Map => ValueKind::Map as u8,
|
||||
ValueKind::MarkStart => ValueKind::MarkStart as u8,
|
||||
ValueKind::TreeMove => ValueKind::TreeMove as u8,
|
||||
ValueKind::Binary => ValueKind::Binary as u8,
|
||||
ValueKind::Unknown => panic!("Unknown value kind"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Value<'a> {
|
||||
pub fn kind(&self) -> ValueKind {
|
||||
match self {
|
||||
|
|
Loading…
Reference in a new issue