fix: fuzz

This commit is contained in:
leeeon233 2023-03-15 11:52:47 +08:00
parent e2e7f9cdac
commit fba6024754
7 changed files with 249 additions and 105 deletions

View file

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

View file

@ -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,6 +99,9 @@ impl MapContainer {
if h.should_notify(self.id()) {
let mut diff = MapDiff::new();
if let Some(old_value) = self.get(&key).cloned() {
if value.is_null() {
diff.deleted.insert(key.clone(), old_value);
} else {
diff.updated.insert(
key.clone(),
ValuePair {
@ -103,6 +109,7 @@ impl MapContainer {
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

View file

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

View file

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

View file

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

View file

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

View file

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