diff --git a/eden/scm/lib/dag/src/idmap/indexedlog_idmap.rs b/eden/scm/lib/dag/src/idmap/indexedlog_idmap.rs index 1e7064439e..571287d5df 100644 --- a/eden/scm/lib/dag/src/idmap/indexedlog_idmap.rs +++ b/eden/scm/lib/dag/src/idmap/indexedlog_idmap.rs @@ -11,6 +11,7 @@ use crate::errors::bug; use crate::errors::programming; use crate::id::{Group, Id, VertexName}; use crate::ops::IdConvert; +use crate::ops::Persist; use crate::ops::PrefixLookup; use crate::Result; use byteorder::{BigEndian, ReadBytesExt}; @@ -126,20 +127,10 @@ impl IdMap { // Take a filesystem lock. The file name 'lock' is taken by indexedlog // running on Windows, so we choose another file name here. - let lock_file = { - let mut path = self.path.clone(); - path.push("wlock"); - File::open(&path).or_else(|_| { - fs::OpenOptions::new() - .write(true) - .create_new(true) - .open(&path) - })? - }; - lock_file.lock_exclusive()?; + let lock_file = self.lock()?; // Reload. So we get latest data. - self.reload()?; + self.reload(&lock_file)?; Ok(SyncableIdMap { map: self, @@ -147,15 +138,6 @@ impl IdMap { }) } - /// Reload from the filesystem. Discard pending changes. - fn reload(&mut self) -> Result<()> { - self.log.clear_dirty()?; - self.log.sync()?; - // Invalidate the next free id cache. - self.cached_next_free_ids = Default::default(); - Ok(()) - } - /// Find name by a specified integer id. pub fn find_name_by_id(&self, id: Id) -> Result> { let key = id.0.to_be_bytes(); @@ -391,6 +373,41 @@ impl IdMapWrite for IdMap { } } +impl Persist for IdMap { + type Lock = File; + + fn lock(&self) -> Result { + let lock_file = { + let mut path = self.path.clone(); + path.push("wlock"); + File::open(&path).or_else(|_| { + fs::OpenOptions::new() + .write(true) + .create_new(true) + .open(&path) + })? + }; + lock_file.lock_exclusive()?; + Ok(lock_file) + } + + fn reload(&mut self, _lock: &Self::Lock) -> Result<()> { + self.log.clear_dirty()?; + self.log.sync()?; + // Invalidate the next free id cache. + self.cached_next_free_ids = Default::default(); + Ok(()) + } + + fn persist(&mut self, _lock: &Self::Lock) -> Result<()> { + if self.need_rebuild_non_master { + return bug("cannot persist with re-assigned ids unresolved"); + } + self.log.sync()?; + Ok(()) + } +} + impl PrefixLookup for IdMap { fn vertexes_by_hex_prefix(&self, hex_prefix: &[u8], limit: usize) -> Result> { self.find_names_by_hex_prefix(hex_prefix, limit) diff --git a/eden/scm/lib/dag/src/idmap/mem_idmap.rs b/eden/scm/lib/dag/src/idmap/mem_idmap.rs index 4ddd44ae5a..2eb74037aa 100644 --- a/eden/scm/lib/dag/src/idmap/mem_idmap.rs +++ b/eden/scm/lib/dag/src/idmap/mem_idmap.rs @@ -8,6 +8,7 @@ use super::IdMapWrite; use crate::id::{Group, Id, VertexName}; use crate::ops::IdConvert; +use crate::ops::Persist; use crate::ops::PrefixLookup; use crate::Result; use std::collections::{BTreeMap, HashMap}; @@ -91,6 +92,22 @@ impl IdMapWrite for MemIdMap { } } +impl Persist for MemIdMap { + type Lock = (); + + fn lock(&self) -> Result { + Ok(()) + } + + fn reload(&mut self, _lock: &Self::Lock) -> Result<()> { + Ok(()) + } + + fn persist(&mut self, _lock: &Self::Lock) -> Result<()> { + Ok(()) + } +} + impl PrefixLookup for MemIdMap { fn vertexes_by_hex_prefix(&self, hex_prefix: &[u8], limit: usize) -> Result> { let start = VertexName::from_hex(hex_prefix)?;