mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 12:57:20 +00:00
fix: fix memory leak
This commit is contained in:
parent
cf11e1ff4b
commit
b582e005cb
6 changed files with 241 additions and 38 deletions
|
@ -1,7 +1,2 @@
|
|||
[workspace]
|
||||
members = ["crates/*"]
|
||||
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = 3
|
||||
|
|
|
@ -3,7 +3,10 @@ use std::ptr::NonNull;
|
|||
use enum_as_inner::EnumAsInner;
|
||||
use fxhash::FxHashMap;
|
||||
|
||||
use crate::{log_store::LogStoreRef, LogStore};
|
||||
use crate::{
|
||||
log_store::{LogStoreRef, LogStoreWeakRef},
|
||||
LogStore,
|
||||
};
|
||||
|
||||
use super::{
|
||||
map::MapContainer, text::text_container::TextContainer, Container, ContainerID, ContainerType,
|
||||
|
@ -80,7 +83,7 @@ impl ContainerManager {
|
|||
&mut self,
|
||||
id: ContainerID,
|
||||
container_type: ContainerType,
|
||||
log_store: LogStoreRef,
|
||||
log_store: LogStoreWeakRef,
|
||||
) -> ContainerInstance {
|
||||
match container_type {
|
||||
ContainerType::Map => ContainerInstance::Map(Box::new(MapContainer::new(id))),
|
||||
|
@ -109,7 +112,7 @@ impl ContainerManager {
|
|||
pub fn get_or_create(
|
||||
&mut self,
|
||||
id: &ContainerID,
|
||||
log_store: LogStoreRef,
|
||||
log_store: LogStoreWeakRef,
|
||||
) -> &mut ContainerInstance {
|
||||
if !self.containers.contains_key(id) {
|
||||
let container = self.create(id.clone(), id.container_type(), log_store);
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
container::{list::list_op::ListOp, Container, ContainerID, ContainerType},
|
||||
dag::{Dag, DagUtils},
|
||||
id::ID,
|
||||
log_store::LogStoreRef,
|
||||
log_store::LogStoreWeakRef,
|
||||
op::{InsertContent, Op, OpContent, OpProxy},
|
||||
smstring::SmString,
|
||||
span::{HasIdSpan, IdSpan},
|
||||
|
@ -28,7 +28,7 @@ struct DagNode {
|
|||
#[derive(Debug)]
|
||||
pub struct TextContainer {
|
||||
id: ContainerID,
|
||||
log_store: LogStoreRef,
|
||||
log_store: LogStoreWeakRef,
|
||||
state: RleTree<ListSlice, ListSliceTreeTrait>,
|
||||
raw_str: StringPool,
|
||||
tracker: Tracker,
|
||||
|
@ -36,7 +36,7 @@ pub struct TextContainer {
|
|||
}
|
||||
|
||||
impl TextContainer {
|
||||
pub fn new(id: ContainerID, log_store: LogStoreRef) -> Self {
|
||||
pub fn new(id: ContainerID, log_store: LogStoreWeakRef) -> Self {
|
||||
Self {
|
||||
id,
|
||||
log_store,
|
||||
|
@ -48,7 +48,7 @@ impl TextContainer {
|
|||
}
|
||||
|
||||
pub fn insert(&mut self, pos: usize, text: &str) -> Option<ID> {
|
||||
let id = if let Ok(mut store) = self.log_store.write() {
|
||||
let id = if let Ok(mut store) = self.log_store.upgrade().unwrap().write() {
|
||||
let id = store.next_id();
|
||||
let slice = ListSlice::from_range(self.raw_str.alloc(text));
|
||||
self.state.insert(pos, slice.clone());
|
||||
|
@ -69,7 +69,7 @@ impl TextContainer {
|
|||
}
|
||||
|
||||
pub fn delete(&mut self, pos: usize, len: usize) -> Option<ID> {
|
||||
let id = if let Ok(mut store) = self.log_store.write() {
|
||||
let id = if let Ok(mut store) = self.log_store.upgrade().unwrap().write() {
|
||||
let id = store.next_id();
|
||||
let op = Op::new(
|
||||
id,
|
||||
|
|
|
@ -87,22 +87,19 @@ impl Actionable for String {
|
|||
}
|
||||
}
|
||||
Action::Del { pos, len } => {
|
||||
if self.len() == 0 {
|
||||
if self.is_empty() {
|
||||
*len = 0;
|
||||
*pos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
let mut changed = false;
|
||||
while !self.is_char_boundary(*pos) {
|
||||
*pos = (*pos + 1) % self.len();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if changed {
|
||||
*len = 1;
|
||||
while !self.is_char_boundary(*pos + *len) {
|
||||
*len += 1;
|
||||
}
|
||||
*len = (*len).min(self.len() - (*pos));
|
||||
while !self.is_char_boundary(*pos + *len) {
|
||||
*len += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +128,7 @@ impl Actionable for TextContainer {
|
|||
}
|
||||
|
||||
pub fn test_single_client(mut actions: Vec<Action>) {
|
||||
let mut store = LoroCore::new(Default::default(), None);
|
||||
let mut store = LoroCore::new(Default::default(), Some(1));
|
||||
let mut text_container = store.get_text_container("haha".into());
|
||||
let mut ground_truth = String::new();
|
||||
let mut applied = Vec::new();
|
||||
|
@ -159,30 +156,238 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test() {
|
||||
test_single_client(vec![
|
||||
test_single_client(vec! [
|
||||
Ins {
|
||||
content: "璤\u{13}\u{13}\u{13}".into(),
|
||||
pos: 243,
|
||||
content: "\u{16}\u{16}\u{16}\u{16}\u{16}#####BBBBSSSSSSSSS".into(),
|
||||
pos: 60797853338129363,
|
||||
},
|
||||
Ins {
|
||||
content: "\0\0\0\0?\0\0\0".into(),
|
||||
pos: 11240984669950312448,
|
||||
content: "\u{13}T0\u{18}5\u{13}".into(),
|
||||
pos: 1369375761697341439,
|
||||
},
|
||||
Ins {
|
||||
content: "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0".into(),
|
||||
pos: 129,
|
||||
content: "\0\0\0SS".into(),
|
||||
pos: 280733345338323,
|
||||
},
|
||||
Ins {
|
||||
content: "**".into(),
|
||||
pos: 5444570,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{13}".into(),
|
||||
pos: 5692550972993381338,
|
||||
},
|
||||
Ins {
|
||||
content: "OOOOOOOOOOOOOOBBBBBBBBBBBBBBBBB#\0\0####".into(),
|
||||
pos: 138028458976,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 91344728162323,
|
||||
pos: 267263250998051,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 6148914691236517150,
|
||||
pos: 4774378554966147091,
|
||||
},
|
||||
Del {
|
||||
pos: 12460594852558187539,
|
||||
len: 1430476722683303114,
|
||||
Ins {
|
||||
content: "BBBBB#\0\0######## \0\0\0######".into(),
|
||||
pos: 3038287259207217298,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 16645325113485036074,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 23362835702677503,
|
||||
},
|
||||
Ins {
|
||||
content: "S".into(),
|
||||
pos: 280733345338323,
|
||||
},
|
||||
Ins {
|
||||
content: "*UUU".into(),
|
||||
pos: 2761092332,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{5ec}".into(),
|
||||
pos: 15332975680940594378,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 3038287259199214554,
|
||||
},
|
||||
Ins {
|
||||
content: "PPPPPPPPPPPPP\u{13}".into(),
|
||||
pos: 6004374254117322995,
|
||||
},
|
||||
Ins {
|
||||
content: "SSSSSS".into(),
|
||||
pos: 48379484722131,
|
||||
},
|
||||
Ins {
|
||||
content: ",\0\0\0UUUU".into(),
|
||||
pos: 2761092332,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{5ec}".into(),
|
||||
pos: 15332975680940594378,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 3038287259199214554,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 5787213827046133840,
|
||||
},
|
||||
Ins {
|
||||
content: "PPPPPPPPPPPPPPPP*****".into(),
|
||||
pos: 2762368,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 0,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 0,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 3038287259199220266,
|
||||
},
|
||||
Ins {
|
||||
content: "*\0\u{13}EEEEEEEEEEEEEEEEEEEEEEEE".into(),
|
||||
pos: 4179340455027348442,
|
||||
},
|
||||
Ins {
|
||||
content: "\0UUUU".into(),
|
||||
pos: 2761092332,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{5ec}".into(),
|
||||
pos: 15332976539934053578,
|
||||
},
|
||||
Ins {
|
||||
content: "ڨ\0\0\0*******************".into(),
|
||||
pos: 3038287259199220352,
|
||||
},
|
||||
Ins {
|
||||
content: "*&*****".into(),
|
||||
pos: 6004234345560396434,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 3038287259199220307,
|
||||
},
|
||||
Ins {
|
||||
content: "******".into(),
|
||||
pos: 3038287259889816210,
|
||||
},
|
||||
Ins {
|
||||
content: "*****".into(),
|
||||
pos: 11350616413819538,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 6004234345560363859,
|
||||
},
|
||||
Ins {
|
||||
content: "S".into(),
|
||||
pos: 60797853338129363,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{13}T3\u{18}5\u{13}".into(),
|
||||
pos: 1369375761697341439,
|
||||
},
|
||||
Ins {
|
||||
content: "\0\0\0SS".into(),
|
||||
pos: 280733345338323,
|
||||
},
|
||||
Ins {
|
||||
content: "*UUU".into(),
|
||||
pos: 2761092332,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{5ec}".into(),
|
||||
pos: 15332975680940594378,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 3038287259199214554,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 5787213827046133840,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 5787213827046133840,
|
||||
},
|
||||
Ins {
|
||||
content: "PPPP*****".into(),
|
||||
pos: 2762368,
|
||||
},
|
||||
Ins {
|
||||
content: "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0******".into(),
|
||||
pos: 3038287259199220266,
|
||||
},
|
||||
Ins {
|
||||
content: "EEEEEEEEEEEEEEEEEEEEEEE".into(),
|
||||
pos: 4179340455027348442,
|
||||
},
|
||||
Ins {
|
||||
content: "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 ,\0\0\0UUUU".into(),
|
||||
pos: 2761092332,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{5ec}".into(),
|
||||
pos: 14483766535198004426,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 3038240898625886739,
|
||||
},
|
||||
Ins {
|
||||
content: "*************".into(),
|
||||
pos: 3038287259199220352,
|
||||
},
|
||||
Ins {
|
||||
content: "*&*****".into(),
|
||||
pos: 6004234345560396434,
|
||||
},
|
||||
Ins {
|
||||
content: "S*********\0*******".into(),
|
||||
pos: 3038287259889816210,
|
||||
},
|
||||
Ins {
|
||||
content: "*****".into(),
|
||||
pos: 11350616413819538,
|
||||
},
|
||||
Ins {
|
||||
content: "SSSSSSSSSSSSS".into(),
|
||||
pos: 60797853338129363,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{13}T4\u{18}5\u{13}".into(),
|
||||
pos: 1369375761697341439,
|
||||
},
|
||||
Ins {
|
||||
content: "\0\0\0SS".into(),
|
||||
pos: 3834029289772372947,
|
||||
},
|
||||
Ins {
|
||||
content: "55555555555555555555555555555555555555555555555555555555555555555555555555555555555".into(),
|
||||
pos: 280603991029045,
|
||||
},
|
||||
Ins {
|
||||
content: "".into(),
|
||||
pos: 356815350314,
|
||||
},
|
||||
Ins {
|
||||
content: "\u{13}\0\u{13}".into(),
|
||||
pos: 1369095330717705178,
|
||||
},
|
||||
])
|
||||
}
|
||||
|
|
|
@ -267,7 +267,7 @@ impl LogStore {
|
|||
#[inline]
|
||||
fn apply_remote_op(&mut self, change: &Change, op: &Op) {
|
||||
let mut container = self.container.write().unwrap();
|
||||
let container = container.get_or_create(op.container(), self.to_self.upgrade().unwrap());
|
||||
let container = container.get_or_create(op.container(), self.to_self.clone());
|
||||
container.apply(&OpProxy::new(change, op, None), self);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ impl LoroCore {
|
|||
a.map_mut(|x| {
|
||||
x.get_or_create(
|
||||
&ContainerID::new_root(name, container),
|
||||
self.log_store.clone(),
|
||||
Arc::downgrade(&self.log_store),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ impl LoroCore {
|
|||
a.map_mut(|x| {
|
||||
x.get_or_create(
|
||||
&ContainerID::new_root(name, ContainerType::Map),
|
||||
self.log_store.clone(),
|
||||
Arc::downgrade(&self.log_store),
|
||||
)
|
||||
.as_map_mut()
|
||||
.unwrap()
|
||||
|
@ -78,7 +78,7 @@ impl LoroCore {
|
|||
a.map_mut(|x| {
|
||||
x.get_or_create(
|
||||
&ContainerID::new_root(name, ContainerType::Text),
|
||||
self.log_store.clone(),
|
||||
Arc::downgrade(&self.log_store),
|
||||
)
|
||||
.as_text_mut()
|
||||
.unwrap()
|
||||
|
|
Loading…
Reference in a new issue