git_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: git_lock::acquire::Fail,
11 ) -> Result<packed::Transaction, transaction::Error> {
12 let lock = git_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 ))
20 }
21
22 pub fn open_packed_buffer(&self) -> Result<Option<packed::Buffer>, packed::buffer::open::Error> {
24 let need_more_than_this_many_bytes_to_use_mmap = 32 * 1024;
25 match packed::Buffer::open(self.packed_refs_path(), need_more_than_this_many_bytes_to_use_mmap) {
26 Ok(buf) => Ok(Some(buf)),
27 Err(packed::buffer::open::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => Ok(None),
28 Err(err) => Err(err),
29 }
30 }
31
32 pub fn cached_packed_buffer(
38 &self,
39 ) -> Result<Option<file::packed::SharedBufferSnapshot>, packed::buffer::open::Error> {
40 self.assure_packed_refs_uptodate()
41 }
42
43 pub fn packed_refs_path(&self) -> PathBuf {
45 self.common_dir_resolved().join("packed-refs")
46 }
47
48 pub(crate) fn packed_refs_lock_path(&self) -> PathBuf {
49 let mut p = self.packed_refs_path();
50 p.set_extension("lock");
51 p
52 }
53}
54
55pub mod transaction {
57
58 use crate::store_impl::packed;
59
60 #[derive(Debug, thiserror::Error)]
62 #[allow(missing_docs)]
63 pub enum Error {
64 #[error("An existing pack couldn't be opened or read when preparing a transaction")]
65 BufferOpen(#[from] packed::buffer::open::Error),
66 #[error("The lock for a packed transaction could not be obtained")]
67 TransactionLock(#[from] git_lock::acquire::Error),
68 }
69}
70
71pub type SharedBufferSnapshot = git_features::fs::SharedSnapshot<packed::Buffer>;
73
74pub(crate) mod modifiable {
75 use git_features::threading::OwnShared;
76
77 use crate::{file, packed};
78
79 pub(crate) type MutableSharedBuffer = OwnShared<git_features::fs::MutableSnapshot<packed::Buffer>>;
80
81 impl file::Store {
82 pub(crate) fn force_refresh_packed_buffer(&self) -> Result<(), packed::buffer::open::Error> {
83 self.packed.force_refresh(|| {
84 let modified = self.packed_refs_path().metadata()?.modified()?;
85 self.open_packed_buffer().map(|packed| Some(modified).zip(packed))
86 })
87 }
88 pub(crate) fn assure_packed_refs_uptodate(
89 &self,
90 ) -> Result<Option<super::SharedBufferSnapshot>, packed::buffer::open::Error> {
91 self.packed.recent_snapshot(
92 || self.packed_refs_path().metadata().and_then(|m| m.modified()).ok(),
93 || self.open_packed_buffer(),
94 )
95 }
96 }
97}