mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-06 12:25:03 +00:00
refactor: remove isomophic and parallel feature
features should be additive in Rust
This commit is contained in:
parent
ea2f1256b8
commit
8dc788e404
9 changed files with 60 additions and 132 deletions
|
@ -48,7 +48,6 @@ doctest = false
|
|||
|
||||
[features]
|
||||
wasm = ["wasm-bindgen", "js-sys"]
|
||||
parallel = []
|
||||
mem-prof = []
|
||||
# whether to use list slice instead of raw str in text container
|
||||
fuzzing = ["crdt-list/fuzzing", "rand", "arbitrary", "tabled"]
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
sync::{RwLockReadGuard, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
use enum_as_inner::EnumAsInner;
|
||||
use fxhash::FxHashMap;
|
||||
use owning_ref::{OwningRef, OwningRefMut};
|
||||
|
||||
use crate::{
|
||||
isomorph::{IsoRef, IsoRefMut},
|
||||
log_store::LogStoreWeakRef,
|
||||
op::RemoteOp,
|
||||
span::IdSpan,
|
||||
LogStore, LoroError,
|
||||
};
|
||||
use crate::{log_store::LogStoreWeakRef, op::RemoteOp, span::IdSpan, LogStore, LoroError};
|
||||
|
||||
use super::{
|
||||
map::MapContainer, text::text_container::TextContainer, Container, ContainerID, ContainerType,
|
||||
|
@ -153,21 +150,23 @@ impl ContainerManager {
|
|||
}
|
||||
|
||||
pub struct ContainerRefMut<'a, T> {
|
||||
value: OwningRefMut<IsoRefMut<'a, ContainerManager>, Box<T>>,
|
||||
value: OwningRefMut<RwLockWriteGuard<'a, ContainerManager>, Box<T>>,
|
||||
}
|
||||
|
||||
pub struct ContainerRef<'a, T> {
|
||||
value: OwningRef<IsoRef<'a, ContainerManager>, Box<T>>,
|
||||
value: OwningRef<RwLockReadGuard<'a, ContainerManager>, Box<T>>,
|
||||
}
|
||||
|
||||
impl<'a, T> From<OwningRefMut<IsoRefMut<'a, ContainerManager>, Box<T>>> for ContainerRefMut<'a, T> {
|
||||
fn from(value: OwningRefMut<IsoRefMut<'a, ContainerManager>, Box<T>>) -> Self {
|
||||
impl<'a, T> From<OwningRefMut<RwLockWriteGuard<'a, ContainerManager>, Box<T>>>
|
||||
for ContainerRefMut<'a, T>
|
||||
{
|
||||
fn from(value: OwningRefMut<RwLockWriteGuard<'a, ContainerManager>, Box<T>>) -> Self {
|
||||
ContainerRefMut { value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> From<OwningRef<IsoRef<'a, ContainerManager>, Box<T>>> for ContainerRef<'a, T> {
|
||||
fn from(value: OwningRef<IsoRef<'a, ContainerManager>, Box<T>>) -> Self {
|
||||
impl<'a, T> From<OwningRef<RwLockReadGuard<'a, ContainerManager>, Box<T>>> for ContainerRef<'a, T> {
|
||||
fn from(value: OwningRef<RwLockReadGuard<'a, ContainerManager>, Box<T>>) -> Self {
|
||||
ContainerRef { value }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ impl MapContainer {
|
|||
pub fn insert(&mut self, key: InternalString, value: InsertValue) {
|
||||
let self_id = &self.id;
|
||||
let m = self.store.upgrade().unwrap();
|
||||
let mut store = m.write();
|
||||
let mut store = m.write().unwrap();
|
||||
let client_id = store.this_client_id;
|
||||
let order = TotalOrderStamp {
|
||||
client_id,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#![cfg(test)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use fxhash::FxHashMap;
|
||||
use proptest::prelude::*;
|
||||
use proptest::proptest;
|
||||
|
||||
use crate::isomorph::Irc;
|
||||
use crate::value::proptest::gen_insert_value;
|
||||
use crate::Container;
|
||||
|
||||
|
@ -15,7 +15,7 @@ use crate::{fx_map, value::InsertValue, LoroCore, LoroValue};
|
|||
#[test]
|
||||
fn basic() {
|
||||
let mut loro = LoroCore::default();
|
||||
let _weak = Irc::downgrade(&loro.log_store);
|
||||
let _weak = Arc::downgrade(&loro.log_store);
|
||||
let mut container = loro.get_or_create_root_map("map").unwrap();
|
||||
container.insert("haha".into(), InsertValue::Int32(1));
|
||||
let ans = fx_map!(
|
||||
|
@ -37,7 +37,7 @@ mod map_proptest {
|
|||
value in prop::collection::vec(gen_insert_value(), 0..10 * PROPTEST_FACTOR_10)
|
||||
) {
|
||||
let mut loro = LoroCore::default();
|
||||
let _weak = Irc::downgrade(&loro.log_store);
|
||||
let _weak = Arc::downgrade(&loro.log_store);
|
||||
let mut container = loro.get_or_create_root_map("map").unwrap();
|
||||
let mut map: HashMap<String, InsertValue> = HashMap::new();
|
||||
for (k, v) in key.iter().zip(value.iter()) {
|
||||
|
|
|
@ -62,7 +62,7 @@ impl TextContainer {
|
|||
}
|
||||
|
||||
let s = self.log_store.upgrade().unwrap();
|
||||
let mut store = s.write();
|
||||
let mut store = s.write().unwrap();
|
||||
let id = store.next_id();
|
||||
let slice = self.raw_str.alloc(text);
|
||||
self.state.insert(pos, slice.clone());
|
||||
|
@ -93,7 +93,7 @@ impl TextContainer {
|
|||
}
|
||||
|
||||
let s = self.log_store.upgrade().unwrap();
|
||||
let mut store = s.write();
|
||||
let mut store = s.write().unwrap();
|
||||
let id = store.next_id();
|
||||
let op = Op::new(
|
||||
id,
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
#![allow(unused)]
|
||||
use std::{
|
||||
cell::{Ref, RefCell, RefMut},
|
||||
rc::{Rc, Weak as RcWeak},
|
||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard, Weak as ArcWeak},
|
||||
};
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) type Irc<T> = Arc<T>;
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
pub(crate) type Irc<T> = Rc<T>;
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) type IsoWeak<T> = ArcWeak<T>;
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
pub(crate) type IsoWeak<T> = RcWeak<T>;
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct IsoRw<T>(RwLock<T>);
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct IsoRw<T>(RefCell<T>);
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) type IsoRef<'a, T> = RwLockReadGuard<'a, T>;
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
pub(crate) type IsoRef<'a, T> = Ref<'a, T>;
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub(crate) type IsoRefMut<'a, T> = RwLockWriteGuard<'a, T>;
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
pub(crate) type IsoRefMut<'a, T> = RefMut<'a, T>;
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
mod rw_parallel {
|
||||
use super::*;
|
||||
|
||||
impl<T> IsoRw<T> {
|
||||
#[inline(always)]
|
||||
pub fn new(t: T) -> Self {
|
||||
Self(RwLock::new(t))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn read(&self) -> std::sync::RwLockReadGuard<T> {
|
||||
self.0.read().unwrap()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write(&self) -> std::sync::RwLockWriteGuard<T> {
|
||||
self.0.write().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
mod rw_single {
|
||||
use std::{cell::RefCell, ops::Deref};
|
||||
|
||||
use super::IsoRw;
|
||||
|
||||
impl<T> IsoRw<T> {
|
||||
#[inline(always)]
|
||||
pub fn new(t: T) -> Self {
|
||||
IsoRw(RefCell::new(t))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn read(&self) -> std::cell::Ref<T> {
|
||||
self.0.borrow()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write(&self) -> std::cell::RefMut<T> {
|
||||
self.0.borrow_mut()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@ pub mod version;
|
|||
mod error;
|
||||
#[cfg(feature = "fuzzing")]
|
||||
pub mod fuzz;
|
||||
mod isomorph;
|
||||
mod loro;
|
||||
mod smstring;
|
||||
mod snapshot;
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
//!
|
||||
//!
|
||||
mod iter;
|
||||
use std::{marker::PhantomPinned, ops::Range};
|
||||
use std::{
|
||||
marker::PhantomPinned,
|
||||
ops::Range,
|
||||
sync::{Arc, RwLock, Weak},
|
||||
};
|
||||
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
|
||||
|
@ -20,7 +24,6 @@ use crate::{
|
|||
dag::Dag,
|
||||
debug_log,
|
||||
id::{ClientID, ContainerIdx, Counter},
|
||||
isomorph::{Irc, IsoRw, IsoWeak},
|
||||
op::RemoteOp,
|
||||
span::{HasCounterSpan, HasIdSpan, HasLamportSpan, IdSpan},
|
||||
Lamport, Op, Timestamp, VersionVector, ID,
|
||||
|
@ -44,8 +47,8 @@ impl Default for GcConfig {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) type LogStoreRef = Irc<IsoRw<LogStore>>;
|
||||
pub(crate) type LogStoreWeakRef = IsoWeak<IsoRw<LogStore>>;
|
||||
pub(crate) type LogStoreRef = Arc<RwLock<LogStore>>;
|
||||
pub(crate) type LogStoreWeakRef = Weak<RwLock<LogStore>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// LogStore stores the full history of Loro
|
||||
|
@ -64,8 +67,8 @@ pub struct LogStore {
|
|||
pub(crate) this_client_id: ClientID,
|
||||
frontier: SmallVec<[ID; 2]>,
|
||||
/// CRDT container manager
|
||||
pub(crate) container: IsoWeak<IsoRw<ContainerManager>>,
|
||||
to_self: IsoWeak<IsoRw<LogStore>>,
|
||||
pub(crate) container: Weak<RwLock<ContainerManager>>,
|
||||
to_self: Weak<RwLock<LogStore>>,
|
||||
container_to_idx: FxHashMap<ContainerID, u32>,
|
||||
idx_to_container: Vec<ContainerID>,
|
||||
_pin: PhantomPinned,
|
||||
|
@ -75,11 +78,11 @@ impl LogStore {
|
|||
pub(crate) fn new(
|
||||
mut cfg: Configure,
|
||||
client_id: Option<ClientID>,
|
||||
container: IsoWeak<IsoRw<ContainerManager>>,
|
||||
) -> Irc<IsoRw<Self>> {
|
||||
container: Weak<RwLock<ContainerManager>>,
|
||||
) -> Arc<RwLock<Self>> {
|
||||
let this_client_id = client_id.unwrap_or_else(|| cfg.rand.next_u64());
|
||||
Irc::new_cyclic(|x| {
|
||||
IsoRw::new(Self {
|
||||
Arc::new_cyclic(|x| {
|
||||
RwLock::new(Self {
|
||||
cfg,
|
||||
this_client_id,
|
||||
changes: FxHashMap::default(),
|
||||
|
@ -175,7 +178,7 @@ impl LogStore {
|
|||
|
||||
fn change_to_export_format(&self, change: Change) -> Change<RemoteOp> {
|
||||
let upgraded = self.container.upgrade().unwrap();
|
||||
let container_manager = upgraded.read();
|
||||
let container_manager = upgraded.read().unwrap();
|
||||
let mut ops = RleVec::new();
|
||||
for mut op in change.ops.into_iter() {
|
||||
let container = container_manager
|
||||
|
@ -296,7 +299,7 @@ impl LogStore {
|
|||
|
||||
// TODO: find a way to remove this clone? we don't need change in apply method actually
|
||||
let upgraded = self.container.upgrade().unwrap();
|
||||
let mut container_manager = upgraded.write();
|
||||
let mut container_manager = upgraded.write().unwrap();
|
||||
let change = self.change_to_imported_format(&mut container_manager, change);
|
||||
let v = self
|
||||
.changes
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use owning_ref::{OwningRef, OwningRefMut};
|
||||
|
||||
use crate::{
|
||||
|
@ -10,14 +12,13 @@ use crate::{
|
|||
ContainerID, ContainerType,
|
||||
},
|
||||
id::ClientID,
|
||||
isomorph::{Irc, IsoRw},
|
||||
op::RemoteOp,
|
||||
LogStore, LoroError, VersionVector,
|
||||
};
|
||||
|
||||
pub struct LoroCore {
|
||||
pub(crate) log_store: Irc<IsoRw<LogStore>>,
|
||||
pub(crate) container: Irc<IsoRw<ContainerManager>>,
|
||||
pub(crate) log_store: Arc<RwLock<LogStore>>,
|
||||
pub(crate) container: Arc<RwLock<ContainerManager>>,
|
||||
}
|
||||
|
||||
impl Default for LoroCore {
|
||||
|
@ -28,8 +29,8 @@ impl Default for LoroCore {
|
|||
|
||||
impl LoroCore {
|
||||
pub fn new(cfg: Configure, client_id: Option<ClientID>) -> Self {
|
||||
let container = Irc::new(IsoRw::new(ContainerManager::new()));
|
||||
let weak = Irc::downgrade(&container);
|
||||
let container = Arc::new(RwLock::new(ContainerManager::new()));
|
||||
let weak = Arc::downgrade(&container);
|
||||
Self {
|
||||
log_store: LogStore::new(cfg, client_id, weak),
|
||||
container,
|
||||
|
@ -37,7 +38,7 @@ impl LoroCore {
|
|||
}
|
||||
|
||||
pub fn vv(&self) -> VersionVector {
|
||||
self.log_store.read().get_vv().clone()
|
||||
self.log_store.read().unwrap().get_vv().clone()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -45,10 +46,13 @@ impl LoroCore {
|
|||
&mut self,
|
||||
name: &str,
|
||||
) -> Result<ContainerRefMut<MapContainer>, LoroError> {
|
||||
let mut a = OwningRefMut::new(self.container.write());
|
||||
let mut a = OwningRefMut::new(self.container.write().unwrap());
|
||||
let id = ContainerID::new_root(name, ContainerType::Map);
|
||||
self.log_store.write().get_or_create_container_idx(&id);
|
||||
let ptr = Irc::downgrade(&self.log_store);
|
||||
self.log_store
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_or_create_container_idx(&id);
|
||||
let ptr = Arc::downgrade(&self.log_store);
|
||||
a.get_or_create(&id, ptr)?;
|
||||
Ok(
|
||||
a.map_mut(move |x| x.get_mut(&id).unwrap().as_map_mut().unwrap())
|
||||
|
@ -61,10 +65,13 @@ impl LoroCore {
|
|||
&mut self,
|
||||
name: &str,
|
||||
) -> Result<ContainerRefMut<TextContainer>, LoroError> {
|
||||
let mut a = OwningRefMut::new(self.container.write());
|
||||
let mut a = OwningRefMut::new(self.container.write().unwrap());
|
||||
let id = ContainerID::new_root(name, ContainerType::Text);
|
||||
self.log_store.write().get_or_create_container_idx(&id);
|
||||
let ptr = Irc::downgrade(&self.log_store);
|
||||
self.log_store
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_or_create_container_idx(&id);
|
||||
let ptr = Arc::downgrade(&self.log_store);
|
||||
a.get_or_create(&id, ptr)?;
|
||||
Ok(
|
||||
a.map_mut(move |x| x.get_mut(&id).unwrap().as_text_mut().unwrap())
|
||||
|
@ -77,7 +84,7 @@ impl LoroCore {
|
|||
&mut self,
|
||||
id: &ContainerID,
|
||||
) -> Result<ContainerRefMut<MapContainer>, LoroError> {
|
||||
let a = OwningRefMut::new(self.container.write());
|
||||
let a = OwningRefMut::new(self.container.write().unwrap());
|
||||
Ok(
|
||||
a.map_mut(move |x| x.get_mut(id).unwrap().as_map_mut().unwrap())
|
||||
.into(),
|
||||
|
@ -89,7 +96,7 @@ impl LoroCore {
|
|||
&mut self,
|
||||
id: &ContainerID,
|
||||
) -> Result<ContainerRefMut<TextContainer>, LoroError> {
|
||||
let a = OwningRefMut::new(self.container.write());
|
||||
let a = OwningRefMut::new(self.container.write().unwrap());
|
||||
Ok(
|
||||
a.map_mut(move |x| x.get_mut(id).unwrap().as_text_mut().unwrap())
|
||||
.into(),
|
||||
|
@ -101,23 +108,23 @@ impl LoroCore {
|
|||
&self,
|
||||
id: &ContainerID,
|
||||
) -> Result<ContainerRef<TextContainer>, LoroError> {
|
||||
let a = OwningRef::new(self.container.read());
|
||||
let a = OwningRef::new(self.container.read().unwrap());
|
||||
Ok(a.map(move |x| x.get(id).unwrap().as_text().unwrap()).into())
|
||||
}
|
||||
|
||||
pub fn export(&self, remote_vv: VersionVector) -> Vec<Change<RemoteOp>> {
|
||||
let store = self.log_store.read();
|
||||
let store = self.log_store.read().unwrap();
|
||||
store.export(&remote_vv)
|
||||
}
|
||||
|
||||
pub fn import(&mut self, changes: Vec<Change<RemoteOp>>) {
|
||||
let mut store = self.log_store.write();
|
||||
let mut store = self.log_store.write().unwrap();
|
||||
store.import(changes)
|
||||
}
|
||||
|
||||
#[cfg(feature = "fuzzing")]
|
||||
pub fn debug_inspect(&self) {
|
||||
self.log_store.write().debug_inspect();
|
||||
self.container.write().debug_inspect();
|
||||
self.log_store.write().unwrap().debug_inspect();
|
||||
self.container.write().unwrap().debug_inspect();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue