fix: fix memory leak

This commit is contained in:
Zixuan Chen 2022-10-20 19:51:38 +08:00
parent cf11e1ff4b
commit b582e005cb
6 changed files with 241 additions and 38 deletions

View file

@ -1,7 +1,2 @@
[workspace]
members = ["crates/*"]
[profile.release]
lto = true
opt-level = 3

View file

@ -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);

View file

@ -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,

View file

@ -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,
},
])
}

View file

@ -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);
}

View file

@ -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()