use std::path::PathBuf;
use crate::store_impl::{file, packed};
impl file::Store {
pub(crate) fn packed_transaction(
&self,
lock_mode: gix_lock::acquire::Fail,
) -> Result<packed::Transaction, transaction::Error> {
let lock = gix_lock::File::acquire_to_update_resource(self.packed_refs_path(), lock_mode, None)?;
Ok(packed::Transaction::new_from_pack_and_lock(
self.assure_packed_refs_uptodate()?,
lock,
self.precompose_unicode,
self.namespace.clone(),
))
}
pub fn open_packed_buffer(&self) -> Result<Option<packed::Buffer>, packed::buffer::open::Error> {
match packed::Buffer::open(self.packed_refs_path(), self.packed_buffer_mmap_threshold) {
Ok(buf) => Ok(Some(buf)),
Err(packed::buffer::open::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(err) => Err(err),
}
}
pub fn cached_packed_buffer(
&self,
) -> Result<Option<file::packed::SharedBufferSnapshot>, packed::buffer::open::Error> {
self.assure_packed_refs_uptodate()
}
pub fn packed_refs_path(&self) -> PathBuf {
self.common_dir_resolved().join("packed-refs")
}
pub(crate) fn packed_refs_lock_path(&self) -> PathBuf {
let mut p = self.packed_refs_path();
p.set_extension("lock");
p
}
}
pub mod transaction {
use crate::store_impl::packed;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("An existing pack couldn't be opened or read when preparing a transaction")]
BufferOpen(#[from] packed::buffer::open::Error),
#[error("The lock for a packed transaction could not be obtained")]
TransactionLock(#[from] gix_lock::acquire::Error),
}
}
pub type SharedBufferSnapshot = gix_fs::SharedFileSnapshot<packed::Buffer>;
pub(crate) mod modifiable {
use gix_features::threading::OwnShared;
use crate::{file, packed};
pub(crate) type MutableSharedBuffer = OwnShared<gix_fs::SharedFileSnapshotMut<packed::Buffer>>;
impl file::Store {
pub(crate) fn force_refresh_packed_buffer(&self) -> Result<(), packed::buffer::open::Error> {
self.packed.force_refresh(|| {
let modified = self.packed_refs_path().metadata()?.modified()?;
self.open_packed_buffer().map(|packed| Some(modified).zip(packed))
})
}
pub(crate) fn assure_packed_refs_uptodate(
&self,
) -> Result<Option<super::SharedBufferSnapshot>, packed::buffer::open::Error> {
self.packed.recent_snapshot(
|| self.packed_refs_path().metadata().and_then(|m| m.modified()).ok(),
|| self.open_packed_buffer(),
)
}
}
}