gix_ref/store/file/
packed.rs1use std::path::PathBuf;
2
3use crate::store_impl::{file, packed};
4
5impl file::Store {
6 pub(crate) fn packed_transaction(
9 &self,
10 lock_mode: gix_lock::acquire::Fail,
11 ) -> Result<packed::Transaction, transaction::Error> {
12 let lock = gix_lock::File::acquire_to_update_resource(self.packed_refs_path(), lock_mode, None)?;
13 Ok(packed::Transaction::new_from_pack_and_lock(
17 self.assure_packed_refs_uptodate()?,
18 lock,
19 self.precompose_unicode,
20 self.namespace.clone(),
21 ))
22 }
23
24 pub fn open_packed_buffer(&self) -> Result<Option<packed::Buffer>, packed::buffer::open::Error> {
29 match packed::Buffer::open(self.packed_refs_path(), self.packed_buffer_mmap_threshold) {
30 Ok(buf) => Ok(Some(buf)),
31 Err(packed::buffer::open::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => Ok(None),
32 Err(err) => Err(err),
33 }
34 }
35
36 pub fn cached_packed_buffer(
42 &self,
43 ) -> Result<Option<file::packed::SharedBufferSnapshot>, packed::buffer::open::Error> {
44 self.assure_packed_refs_uptodate()
45 }
46
47 pub fn packed_refs_path(&self) -> PathBuf {
49 self.common_dir_resolved().join("packed-refs")
50 }
51
52 pub(crate) fn packed_refs_lock_path(&self) -> PathBuf {
53 let mut p = self.packed_refs_path();
54 p.set_extension("lock");
55 p
56 }
57}
58
59pub mod transaction {
61
62 use crate::store_impl::packed;
63
64 #[derive(Debug, thiserror::Error)]
66 #[allow(missing_docs)]
67 pub enum Error {
68 #[error("An existing pack couldn't be opened or read when preparing a transaction")]
69 BufferOpen(#[from] packed::buffer::open::Error),
70 #[error("The lock for a packed transaction could not be obtained")]
71 TransactionLock(#[from] gix_lock::acquire::Error),
72 }
73}
74
75pub type SharedBufferSnapshot = gix_fs::SharedFileSnapshot<packed::Buffer>;
77
78pub(crate) mod modifiable {
79 use gix_features::threading::OwnShared;
80
81 use crate::{file, packed};
82
83 pub(crate) type MutableSharedBuffer = OwnShared<gix_fs::SharedFileSnapshotMut<packed::Buffer>>;
84
85 impl file::Store {
86 pub fn force_refresh_packed_buffer(&self) -> Result<(), packed::buffer::open::Error> {
94 self.packed.force_refresh(|| {
95 let modified = self.packed_refs_path().metadata()?.modified()?;
96 self.open_packed_buffer().map(|packed| Some(modified).zip(packed))
97 })
98 }
99 pub(crate) fn assure_packed_refs_uptodate(
100 &self,
101 ) -> Result<Option<super::SharedBufferSnapshot>, packed::buffer::open::Error> {
102 self.packed.recent_snapshot(
103 || self.packed_refs_path().metadata().and_then(|m| m.modified()).ok(),
104 || self.open_packed_buffer(),
105 )
106 }
107 }
108}