Add LRU cache for external object ID lookup
This commit is contained in:
parent
1f50c386b8
commit
8441fccea2
4 changed files with 46 additions and 5 deletions
automerge
|
@ -26,6 +26,7 @@ tinyvec = { version = "^1.5.1", features = ["alloc"] }
|
|||
unicode-segmentation = "1.7.1"
|
||||
serde = { version = "^1.0", features=["derive"] }
|
||||
dot = { version = "0.1.4", optional = true }
|
||||
lru = "^0.7.1"
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "^0.3.55"
|
||||
|
|
|
@ -21,9 +21,12 @@ impl ExternalOpId {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn into_opid(&self, metadata: &mut OpSetMetadata) -> OpId {
|
||||
let actor = metadata.actors.cache(self.actor.clone());
|
||||
OpId::new(self.counter, actor)
|
||||
pub(crate) fn counter(&self) -> u64 {
|
||||
self.counter
|
||||
}
|
||||
|
||||
pub(crate) fn actor(&self) -> &ActorId {
|
||||
&self.actor
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1110,7 +1110,7 @@ impl Automerge {
|
|||
}
|
||||
|
||||
fn import_opid(&self, opid: &OpId) -> InternalOpId {
|
||||
opid.into_opid(&mut *self.ops.m.borrow_mut())
|
||||
self.ops.m.borrow_mut().import_opid(opid)
|
||||
}
|
||||
|
||||
fn export_opid(&self, opid: &InternalOpId) -> Option<OpId> {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
use crate::op_tree::OpTreeInternal;
|
||||
use crate::query::TreeQuery;
|
||||
use crate::{ActorId, IndexedCache, Key, types::{ObjId, OpId}, Op};
|
||||
use crate::external_types::ExternalOpId;
|
||||
use fxhash::FxBuildHasher;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Debug;
|
||||
|
||||
const EXTERNAL_OP_CACHE_SIZE: usize = 100;
|
||||
|
||||
pub(crate) type OpSet = OpSetInternal<16>;
|
||||
|
||||
|
@ -26,6 +30,7 @@ impl<const B: usize> OpSetInternal<B> {
|
|||
m: Rc::new(RefCell::new(OpSetMetadata {
|
||||
actors: IndexedCache::new(),
|
||||
props: IndexedCache::new(),
|
||||
external_op_cache: lru::LruCache::with_hasher(EXTERNAL_OP_CACHE_SIZE, FxBuildHasher::default())
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
@ -150,12 +155,33 @@ impl<'a, const B: usize> Iterator for Iter<'a, B> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct OpSetMetadata {
|
||||
pub actors: IndexedCache<ActorId>,
|
||||
pub props: IndexedCache<String>,
|
||||
external_op_cache: lru::LruCache<ExternalOpId, OpId, FxBuildHasher>,
|
||||
}
|
||||
|
||||
impl Debug for OpSetMetadata {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("OpSetMetadata")
|
||||
.field("actors", &self.actors)
|
||||
.field("props", &self.props)
|
||||
.field("external_op_cache", &format_args!("LruCache with {} keys", self.external_op_cache.len()))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for OpSetMetadata {
|
||||
fn clone(&self) -> Self {
|
||||
OpSetMetadata {
|
||||
actors: self.actors.clone(),
|
||||
props: self.props.clone(),
|
||||
external_op_cache: lru::LruCache::with_hasher(EXTERNAL_OP_CACHE_SIZE, FxBuildHasher::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl OpSetMetadata {
|
||||
pub fn key_cmp(&self, left: &Key, right: &Key) -> Ordering {
|
||||
match (left, right) {
|
||||
|
@ -167,6 +193,17 @@ impl OpSetMetadata {
|
|||
pub fn lamport_cmp<S: SuccinctLamport>(&self, left: S, right: S) -> Ordering {
|
||||
S::cmp(self, left, right)
|
||||
}
|
||||
|
||||
pub fn import_opid(&mut self, ext_opid: &ExternalOpId) -> OpId {
|
||||
if let Some(opid) = self.external_op_cache.get(ext_opid) {
|
||||
*opid
|
||||
} else {
|
||||
let actor = self.actors.cache(ext_opid.actor().clone());
|
||||
let opid = OpId::new(ext_opid.counter(), actor);
|
||||
self.external_op_cache.put(ext_opid.clone(), opid);
|
||||
opid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lamport timestamps which don't contain their actor ID directly and therefore need access to
|
||||
|
|
Loading…
Add table
Reference in a new issue