mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-06 12:25:03 +00:00
fix: fuzz
This commit is contained in:
parent
e2e7f9cdac
commit
fba6024754
7 changed files with 249 additions and 105 deletions
|
@ -68,7 +68,7 @@ impl ListContainer {
|
|||
if let Some(prelim) = maybe_container {
|
||||
let type_ = value.into_container().unwrap();
|
||||
let (id, idx) = txn.register_container(&self.id, type_);
|
||||
let value = LoroValue::Unresolved(id.clone().into());
|
||||
let value = LoroValue::Unresolved(id.into());
|
||||
self.insert_value(txn, pos, value);
|
||||
prelim.integrate(txn, idx)?;
|
||||
Ok(Some(idx))
|
||||
|
@ -110,7 +110,7 @@ impl ListContainer {
|
|||
local: true,
|
||||
abs_path,
|
||||
};
|
||||
txn.append_event(event);
|
||||
txn.append_event(self.idx, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -140,7 +140,7 @@ impl ListContainer {
|
|||
local: true,
|
||||
abs_path,
|
||||
};
|
||||
txn.append_event(event);
|
||||
txn.append_event(self.idx, event);
|
||||
}
|
||||
}
|
||||
self.state.insert(pos, slice.clone().into());
|
||||
|
@ -187,7 +187,7 @@ impl ListContainer {
|
|||
container_id: self.id.clone(),
|
||||
abs_path,
|
||||
};
|
||||
txn.append_event(event);
|
||||
txn.append_event(self.idx, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -68,6 +68,9 @@ impl MapContainer {
|
|||
}
|
||||
|
||||
pub(crate) fn delete(&mut self, txn: &mut Transaction, key: InternalString) {
|
||||
if self.get(&key).is_none() {
|
||||
return;
|
||||
}
|
||||
self.insert_value(txn, key, LoroValue::Null);
|
||||
}
|
||||
|
||||
|
@ -96,13 +99,17 @@ impl MapContainer {
|
|||
if h.should_notify(self.id()) {
|
||||
let mut diff = MapDiff::new();
|
||||
if let Some(old_value) = self.get(&key).cloned() {
|
||||
diff.updated.insert(
|
||||
key.clone(),
|
||||
ValuePair {
|
||||
old: old_value,
|
||||
new: value.clone(),
|
||||
},
|
||||
);
|
||||
if value.is_null() {
|
||||
diff.deleted.insert(key.clone(), old_value);
|
||||
} else {
|
||||
diff.updated.insert(
|
||||
key.clone(),
|
||||
ValuePair {
|
||||
old: old_value,
|
||||
new: value.clone(),
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
diff.added.insert(key.clone(), value.clone());
|
||||
};
|
||||
|
@ -117,10 +124,13 @@ impl MapContainer {
|
|||
local: true,
|
||||
abs_path,
|
||||
};
|
||||
txn.append_event(event);
|
||||
|
||||
txn.append_event(self.idx, event);
|
||||
}
|
||||
}
|
||||
let value_index = self.pool.alloc(value).start;
|
||||
|
||||
self.update_hierarchy_if_container_is_overwritten(&key, h);
|
||||
self.state.insert(
|
||||
key.clone(),
|
||||
ValueSlot {
|
||||
|
@ -131,7 +141,6 @@ impl MapContainer {
|
|||
},
|
||||
},
|
||||
);
|
||||
self.update_hierarchy_if_container_is_overwritten(&key, h);
|
||||
let id = store.next_id();
|
||||
let op = Op {
|
||||
counter: id.counter,
|
||||
|
@ -460,7 +469,10 @@ impl Map {
|
|||
}
|
||||
|
||||
pub fn delete<T: Transact>(&mut self, txn: &T, key: &str) -> Result<(), LoroError> {
|
||||
self.with_transaction(txn, |txn, x| Ok(x.delete(txn, key.into())))
|
||||
self.with_transaction(txn, |txn, x| {
|
||||
x.delete(txn, key.into());
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Need Clone
|
||||
|
|
|
@ -81,7 +81,7 @@ impl TextContainer {
|
|||
container_id: self.id.clone(),
|
||||
abs_path,
|
||||
};
|
||||
txn.append_event(event);
|
||||
txn.append_event(self.idx, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -111,7 +111,7 @@ impl TextContainer {
|
|||
container_id: self.id.clone(),
|
||||
abs_path,
|
||||
};
|
||||
txn.append_event(event);
|
||||
txn.append_event(self.idx, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -53,7 +53,8 @@ impl<T> MapDiff<T> {
|
|||
}
|
||||
|
||||
for (k, _v) in other.deleted.into_iter() {
|
||||
if let Some(_av) = self.added.remove(&k) {
|
||||
if let Some(av) = self.added.remove(&k) {
|
||||
self.deleted.insert(k, av);
|
||||
} else if let Some(ValuePair { old, .. }) = self.updated.remove(&k) {
|
||||
self.deleted.insert(k, old);
|
||||
} else {
|
||||
|
@ -66,7 +67,7 @@ impl<T> MapDiff<T> {
|
|||
*av = new;
|
||||
} else if let Some(dv) = self.deleted.remove(&k) {
|
||||
self.updated.insert(k, ValuePair { old: dv, new });
|
||||
} else if let Some(ValuePair { old:_, new: n }) = self.updated.get_mut(&k) {
|
||||
} else if let Some(ValuePair { old: _, new: n }) = self.updated.get_mut(&k) {
|
||||
*n = new
|
||||
} else {
|
||||
self.updated.insert(k, ValuePair { old, new });
|
||||
|
|
|
@ -1326,21 +1326,14 @@ mod failed_tests {
|
|||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
key: 1,
|
||||
value: Container(C::List),
|
||||
},
|
||||
Map {
|
||||
List {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Container(C::Map),
|
||||
},
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 1,
|
||||
container_idx: 1,
|
||||
key: 37,
|
||||
value: Null,
|
||||
key: 0,
|
||||
value: I32(1),
|
||||
},
|
||||
],
|
||||
)
|
||||
|
@ -1352,44 +1345,31 @@ mod failed_tests {
|
|||
minify_error(
|
||||
5,
|
||||
vec![
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
key: 1,
|
||||
value: Container(C::List),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
site: 10,
|
||||
container_idx: 255,
|
||||
key: 255,
|
||||
value: Container(C::List),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 255,
|
||||
container_idx: 37,
|
||||
key: 37,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Container(C::Map),
|
||||
},
|
||||
Sync { from: 157, to: 157 },
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 37,
|
||||
container_idx: 37,
|
||||
|
@ -1400,7 +1380,7 @@ mod failed_tests {
|
|||
site: 37,
|
||||
container_idx: 37,
|
||||
key: 37,
|
||||
value: Container(C::List),
|
||||
value: Null,
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
|
@ -1409,6 +1389,18 @@ mod failed_tests {
|
|||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Text {
|
||||
site: 255,
|
||||
container_idx: 255,
|
||||
pos: 10,
|
||||
value: 65290,
|
||||
is_del: true,
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 255,
|
||||
|
@ -1420,42 +1412,6 @@ mod failed_tests {
|
|||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Sync { from: 195, to: 195 },
|
||||
Sync { from: 195, to: 195 },
|
||||
Sync { from: 195, to: 195 },
|
||||
Sync { from: 195, to: 195 },
|
||||
Sync { from: 195, to: 195 },
|
||||
Sync { from: 195, to: 195 },
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Map {
|
||||
site: 37,
|
||||
container_idx: 37,
|
||||
|
@ -1466,7 +1422,13 @@ mod failed_tests {
|
|||
site: 37,
|
||||
container_idx: 37,
|
||||
key: 37,
|
||||
value: Container(C::List),
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 37,
|
||||
container_idx: 37,
|
||||
key: 37,
|
||||
value: Null,
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
|
@ -1476,6 +1438,173 @@ mod failed_tests {
|
|||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
List {
|
||||
site: 92,
|
||||
container_idx: 92,
|
||||
key: 92,
|
||||
value: Container(C::List),
|
||||
},
|
||||
Map {
|
||||
site: 177,
|
||||
container_idx: 255,
|
||||
key: 255,
|
||||
value: I32(1549556779),
|
||||
},
|
||||
List {
|
||||
site: 92,
|
||||
container_idx: 92,
|
||||
key: 92,
|
||||
value: I32(1549556828),
|
||||
},
|
||||
List {
|
||||
site: 92,
|
||||
container_idx: 92,
|
||||
key: 92,
|
||||
value: I32(1549556828),
|
||||
},
|
||||
List {
|
||||
site: 92,
|
||||
container_idx: 92,
|
||||
key: 92,
|
||||
value: I32(1549556828),
|
||||
},
|
||||
List {
|
||||
site: 92,
|
||||
container_idx: 92,
|
||||
key: 92,
|
||||
value: I32(1549556828),
|
||||
},
|
||||
List {
|
||||
site: 92,
|
||||
container_idx: 73,
|
||||
key: 73,
|
||||
value: Null,
|
||||
},
|
||||
List {
|
||||
site: 255,
|
||||
container_idx: 73,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
key: 0,
|
||||
value: Null,
|
||||
},
|
||||
Map {
|
||||
site: 0,
|
||||
container_idx: 0,
|
||||
|
|
|
@ -140,7 +140,7 @@ impl Prelim for PrelimMap {
|
|||
Map::from_instance(container, s.this_client_id)
|
||||
});
|
||||
for (k, value) in self.0.into_iter() {
|
||||
map.with_container(|x| x.insert(txn, k.into(), value));
|
||||
map.with_container(|x| x.insert(txn, k.into(), value))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
collections::BTreeMap,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex, RwLock, Weak},
|
||||
};
|
||||
|
@ -51,7 +52,7 @@ pub struct Transaction {
|
|||
pending_ops: FxHashMap<ContainerIdx, Vec<ID>>,
|
||||
created_container: FxHashMap<ContainerIdx, FxHashSet<ContainerIdx>>,
|
||||
deleted_container: FxHashSet<ContainerIdx>,
|
||||
pending_events: FxHashMap<ContainerID, RawEvent>,
|
||||
pending_events: BTreeMap<ContainerIdx, RawEvent>,
|
||||
start_vv: Frontiers,
|
||||
latest_vv: Frontiers,
|
||||
committed: bool,
|
||||
|
@ -136,19 +137,19 @@ impl Transaction {
|
|||
.push(op_id);
|
||||
}
|
||||
|
||||
pub(crate) fn append_event(&mut self, event: RawEvent) {
|
||||
pub(crate) fn append_event(&mut self, idx: ContainerIdx, event: RawEvent) {
|
||||
// cache events
|
||||
let container_id = &event.container_id;
|
||||
if let Some(old) = self.pending_events.get_mut(container_id) {
|
||||
if let Some(old) = self.pending_events.get_mut(&idx) {
|
||||
compose_two_events(old, event);
|
||||
} else {
|
||||
self.pending_events.insert(container_id.clone(), event);
|
||||
self.pending_events.insert(idx, event);
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_events(&mut self) {
|
||||
let pending_events = std::mem::take(&mut self.pending_events);
|
||||
for (_, mut event) in pending_events {
|
||||
for (_, mut event) in pending_events.into_iter() {
|
||||
event.old_version = self.start_vv.clone();
|
||||
event.new_version = self.latest_vv.clone();
|
||||
let hierarchy = self.hierarchy.upgrade().unwrap();
|
||||
Hierarchy::notify_without_lock(hierarchy, event);
|
||||
|
@ -179,7 +180,8 @@ impl Transaction {
|
|||
let mut hierarchy = hierarchy.try_lock().unwrap();
|
||||
let events = LoroEncoder::decode(&mut store, &mut hierarchy, input)?;
|
||||
for event in events {
|
||||
self.append_event(event)
|
||||
let idx = store.get_container_idx(&event.container_id).unwrap();
|
||||
self.append_event(idx, event)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue