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(
30 self.packed_refs_path(),
31 self.packed_buffer_mmap_threshold,
32 self.object_hash,
33 ) {
34 Ok(buf) => Ok(Some(buf)),
35 Err(packed::buffer::open::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => Ok(None),
36 Err(err) => Err(err),
37 }
38 }
39
40 pub fn cached_packed_buffer(
46 &self,
47 ) -> Result<Option<file::packed::SharedBufferSnapshot>, packed::buffer::open::Error> {
48 self.assure_packed_refs_uptodate()
49 }
50
51 pub fn packed_refs_path(&self) -> PathBuf {
53 self.common_dir_resolved().join("packed-refs")
54 }
55
56 pub(crate) fn packed_refs_lock_path(&self) -> PathBuf {
57 let mut p = self.packed_refs_path();
58 p.set_extension("lock");
59 p
60 }
61}
62
63pub mod transaction {
65
66 use crate::store_impl::packed;
67
68 #[derive(Debug, thiserror::Error)]
70 #[allow(missing_docs)]
71 pub enum Error {
72 #[error("An existing pack couldn't be opened or read when preparing a transaction")]
73 BufferOpen(#[from] packed::buffer::open::Error),
74 #[error("The lock for a packed transaction could not be obtained")]
75 TransactionLock(#[from] gix_lock::acquire::Error),
76 }
77}
78
79pub type SharedBufferSnapshot = gix_fs::SharedFileSnapshot<packed::Buffer>;
81
82pub(crate) mod modifiable {
83 use gix_features::threading::OwnShared;
84
85 use crate::{file, packed};
86
87 pub(crate) type MutableSharedBuffer = OwnShared<gix_fs::SharedFileSnapshotMut<packed::Buffer>>;
88
89 impl file::Store {
90 pub fn force_refresh_packed_buffer(&self) -> Result<(), packed::buffer::open::Error> {
98 self.packed.force_refresh(|| {
99 let modified = self.packed_refs_path().metadata()?.modified()?;
100 self.open_packed_buffer().map(|packed| Some(modified).zip(packed))
101 })
102 }
103 pub(crate) fn assure_packed_refs_uptodate(
104 &self,
105 ) -> Result<Option<super::SharedBufferSnapshot>, packed::buffer::open::Error> {
106 self.packed.recent_snapshot(
107 || self.packed_refs_path().metadata().and_then(|m| m.modified()).ok(),
108 || self.open_packed_buffer(),
109 )
110 }
111 }
112}