chore: bk

This commit is contained in:
Zixuan Chen 2023-07-02 23:24:17 +08:00
parent 2df7429e58
commit abd3e38253
10 changed files with 167 additions and 13 deletions

View file

@ -25,6 +25,7 @@
},
"rust-analyzer.cargo.features": ["test_utils"],
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "stable" },
"editor.formatOnSave": true,
"todo-tree.general.tags": [
"BUG",

13
Cargo.lock generated
View file

@ -528,6 +528,18 @@ dependencies = [
"syn 1.0.107",
]
[[package]]
name = "enum_dispatch"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11f36e95862220b211a6e2aa5eca09b4fa391b13cd52ceb8035a24bf65a79de2"
dependencies = [
"once_cell",
"proc-macro2 1.0.49",
"quote 1.0.23",
"syn 1.0.107",
]
[[package]]
name = "fastrand"
version = "1.8.0"
@ -786,6 +798,7 @@ dependencies = [
"debug-log",
"dhat",
"enum-as-inner",
"enum_dispatch",
"flate2",
"fxhash",
"itertools",

View file

@ -31,6 +31,7 @@ serde_columnar = { version = "0.2.5" }
tracing = { version = "0.1.37" }
append-only-bytes = { version = "0.1.4", features = ["u32_range"] }
itertools = "0.10.5"
enum_dispatch = "0.3.11"
[dev-dependencies]
serde_json = "1.0.87"

View file

@ -19,6 +19,8 @@ pub type Timestamp = i64;
pub type Lamport = u32;
/// A `Change` contains a list of [Op]s.
///
/// When undo/redo we should always undo/redo a whole [Change].
#[derive(Debug, Clone)]
pub struct Change<O = Op> {
pub(crate) ops: RleVec<[O; 2]>,

View file

@ -1,7 +1,6 @@
use std::sync::{Arc, Mutex, Weak};
use std::sync::{Mutex, Weak};
use append_only_bytes::AppendOnlyBytes;
use debug_log::debug_dbg;
use rle::HasLength;
use smallvec::{smallvec, SmallVec};
use tracing::instrument;
@ -21,7 +20,6 @@ use crate::{
op::{InnerContent, Op, RemoteContent, RichOp},
transaction::Transaction,
value::LoroValue,
version::PatchedVersionVector,
LoroError, Transact, VersionVector,
};
@ -29,7 +27,7 @@ use super::{
rope::Rope,
string_pool::{Alive, PoolString, StringPool},
text_content::{ListSlice, SliceRange},
tracker::{Effect, Tracker},
tracker::Tracker,
utf16::count_utf16_chars,
};
@ -87,6 +85,8 @@ impl TextContainer {
Ok(())
}
pub fn diff(&mut self) {}
fn _record_insert_op(
&mut self,
txn: &mut Transaction,

View file

@ -59,7 +59,7 @@ impl GcConfig {
}
}
type ClientChanges = FxHashMap<ClientID, RleVecWithIndex<Change, ChangeMergeCfg>>;
pub(crate) type ClientChanges = FxHashMap<ClientID, RleVecWithIndex<Change, ChangeMergeCfg>>;
pub(crate) type RemoteClientChanges = FxHashMap<ClientID, Vec<Change<RemoteOp>>>;
#[derive(Debug)]

View file

@ -15,11 +15,6 @@ use smallvec::SmallVec;
/// Operation is a unit of change.
///
/// It has 3 types:
/// - Insert
/// - Delete
/// - Restore
///
/// A Op may have multiple atomic operations, since Op can be merged.
#[derive(Debug, Clone)]
pub struct Op {

View file

@ -1,4 +1,43 @@
/// This store the
pub struct OpLog {}
mod dag;
pub struct Dag {}
use fxhash::FxHashMap;
use rle::{HasIndex, HasLength, Mergable, RleVec, Sliceable};
use smallvec::SmallVec;
use crate::change::{Change, Lamport, Timestamp};
use crate::dag::{Dag, DagNode};
use crate::id::{ClientID, Counter, ID};
use crate::log_store::ClientChanges;
use crate::span::{HasId, HasLamport};
use crate::version::{Frontiers, VersionVector};
/// [OpLog] store all the ops i.e. the history.
/// It allows multiple [AppState] to attach to it.
/// So you can derive different versions of the state from the [OpLog].
/// It allows us to build a version control system.
///
#[derive(Debug, Clone)]
pub struct OpLog {
pub(crate) dag: AppDag,
pub(crate) changes: ClientChanges,
pub(crate) latest_lamport: Lamport,
pub(crate) latest_timestamp: Timestamp,
}
/// [AppDag] maintains the causal graph of the app.
/// It's faster to answer the question like what's the LCA version
#[derive(Debug, Clone)]
pub struct AppDag {
map: FxHashMap<ClientID, RleVec<[AppDagNode; 1]>>,
frontiers: Frontiers,
vv: VersionVector,
}
#[derive(Debug, Clone)]
pub struct AppDagNode {
client: ClientID,
cnt: Counter,
lamport: Lamport,
parents: SmallVec<[ID; 2]>,
len: usize,
}

View file

@ -0,0 +1,75 @@
use super::*;
impl HasIndex for AppDagNode {
type Int = Counter;
fn get_start_index(&self) -> Self::Int {
self.cnt
}
fn get_end_index(&self) -> Self::Int {
self.cnt + self.len as Counter
}
}
impl Sliceable for AppDagNode {
fn slice(&self, from: usize, to: usize) -> Self {
AppDagNode {
client: self.client,
cnt: self.cnt + from as Counter,
lamport: self.lamport + from as Lamport,
parents: Default::default(),
len: to - from,
}
}
}
impl HasId for AppDagNode {
fn id_start(&self) -> ID {
ID {
client_id: self.client,
counter: self.cnt,
}
}
}
impl HasLength for AppDagNode {
fn atom_len(&self) -> usize {
self.len
}
fn content_len(&self) -> usize {
self.len
}
}
impl Mergable for AppDagNode {}
impl HasLamport for AppDagNode {
fn lamport(&self) -> Lamport {
self.lamport
}
}
impl DagNode for AppDagNode {
fn deps(&self) -> &[ID] {
&self.parents
}
}
impl Dag for AppDag {
type Node = AppDagNode;
fn frontier(&self) -> &[ID] {
&self.frontiers
}
fn get(&self, id: ID) -> Option<&Self::Node> {
let ID { client_id, counter } = id;
self.map
.get(&client_id)
.and_then(|rle| rle.get(counter).map(|x| x.element))
}
fn vv(&self) -> VersionVector {
self.vv.clone()
}
}

View file

@ -1,7 +1,35 @@
use enum_dispatch::enum_dispatch;
use fxhash::FxHashMap;
use crate::{container::ContainerID, InternalString, VersionVector};
mod list;
mod map;
mod text;
#[enum_dispatch]
pub trait ContainerState: Clone {
fn apply_diff(&mut self);
}
pub struct AppState {
vv: VersionVector,
state: FxHashMap<ContainerID, State>,
}
#[enum_dispatch(ContainerState)]
#[derive(Clone)]
pub enum State {
ListState,
MapState,
TextState,
}
#[derive(Clone)]
pub struct ListState {}
#[derive(Clone)]
pub struct MapState {}
#[derive(Clone)]
pub struct TextState {}