3 ops
::{Deref, DerefMut}
,
10 /// A type to store pack caches in boxes.
11 pub type PackCache
= dyn gix_pack
::cache
::DecodeEntry
+ Send
+ '
static;
12 /// A constructor for boxed pack caches.
13 pub type NewPackCacheFn
= dyn Fn() -> Box
<PackCache
> + Send
+ Sync
+ '
static;
15 /// A type to store object caches in boxes.
16 pub type ObjectCache
= dyn gix_pack
::cache
::Object
+ Send
+ '
static;
17 /// A constructor for boxed object caches.
18 pub type NewObjectCacheFn
= dyn Fn() -> Box
<ObjectCache
> + Send
+ Sync
+ '
static;
20 impl Cache
<crate::store
::Handle
<Rc
<crate::Store
>>> {
21 /// Convert this cache's handle into one that keeps its store in an arc. This creates an entirely new store,
22 /// so should be done early to avoid unnecessary work (and mappings).
23 pub fn into_arc(self) -> std
::io
::Result
<Cache
<crate::store
::Handle
<Arc
<crate::Store
>>>> {
24 let inner
= self.inner
.into_arc()?
;
27 new_pack_cache
: self.new_pack_cache
,
28 new_object_cache
: self.new_object_cache
,
29 pack_cache
: self.pack_cache
,
30 object_cache
: self.object_cache
,
34 impl Cache
<crate::store
::Handle
<Arc
<crate::Store
>>> {
35 /// No op, as we are containing an arc handle already.
36 pub fn into_arc(self) -> std
::io
::Result
<Cache
<crate::store
::Handle
<Arc
<crate::Store
>>>> {
42 /// Dissolve this instance, discard all caches, and return the inner implementation.
43 pub fn into_inner(self) -> S
{
46 /// Use this methods directly after creating a new instance to add a constructor for pack caches.
48 /// These are used to speed up decoding objects which are located in packs, reducing long delta chains by storing
49 /// their intermediate results.
50 pub fn with_pack_cache(mut self, create
: impl Fn() -> Box
<PackCache
> + Send
+ Sync
+ '
static) -> Self {
51 self.pack_cache
= Some(RefCell
::new(create()));
52 self.new_pack_cache
= Some(Arc
::new(create
));
55 /// Use this methods directly after creating a new instance to add a constructor for object caches.
57 /// Only use this kind of cache if the same objects are repeatedly accessed for great speedups, usually during diffing of
59 pub fn with_object_cache(mut self, create
: impl Fn() -> Box
<ObjectCache
> + Send
+ Sync
+ '
static) -> Self {
60 self.object_cache
= Some(RefCell
::new(create()));
61 self.new_object_cache
= Some(Arc
::new(create
));
64 /// Set the pack cache constructor on this instance.
65 pub fn set_pack_cache(&mut self, create
: impl Fn() -> Box
<PackCache
> + Send
+ Sync
+ '
static) {
66 self.pack_cache
= Some(RefCell
::new(create()));
67 self.new_pack_cache
= Some(Arc
::new(create
));
69 /// Set the object cache constructor on this instance.
70 pub fn set_object_cache(&mut self, create
: impl Fn() -> Box
<ObjectCache
> + Send
+ Sync
+ '
static) {
71 self.object_cache
= Some(RefCell
::new(create()));
72 self.new_object_cache
= Some(Arc
::new(create
));
74 /// Return true if an object cache is present.
75 pub fn has_object_cache(&self) -> bool
{
76 self.object_cache
.is_some()
78 /// Return true if a pack cache is present.
79 pub fn has_pack_cache(&self) -> bool
{
80 self.pack_cache
.is_some()
82 /// Remove the current pack cache as well as its constructor from this instance.
83 pub fn unset_pack_cache(&mut self) {
84 self.pack_cache
= None
;
85 self.new_pack_cache
= None
;
87 /// Remove the current object cache as well as its constructor from this instance.
88 pub fn unset_object_cache(&mut self) {
89 self.object_cache
= None
;
90 self.new_object_cache
= None
;
94 impl<S
> From
<S
> for Cache
<S
>
98 fn from(store
: S
) -> Self {
102 new_pack_cache
: None
,
104 new_object_cache
: None
,
109 impl<S
: Clone
> Clone
for Cache
<S
> {
110 fn clone(&self) -> Self {
112 inner
: self.inner
.clone(),
113 new_pack_cache
: self.new_pack_cache
.clone(),
114 new_object_cache
: self.new_object_cache
.clone(),
115 pack_cache
: self.new_pack_cache
.as_ref().map(|create
| RefCell
::new(create())),
116 object_cache
: self.new_object_cache
.as_ref().map(|create
| RefCell
::new(create())),
121 impl<S
> Deref
for Cache
<S
> {
124 fn deref(&self) -> &Self::Target
{
129 impl<S
> DerefMut
for Cache
<S
> {
130 fn deref_mut(&mut self) -> &mut Self::Target
{
136 use std
::{cell::RefCell, io::Read, ops::DerefMut}
;
138 use gix_hash
::{oid, ObjectId}
;
139 use gix_object
::{Data, Kind}
;
140 use gix_pack
::cache
::Object
;
142 use crate::{find::Header, pack::data::entry::Location, Cache}
;
144 impl<S
> crate::Write
for Cache
<S
>
148 fn write_stream(&self, kind
: Kind
, size
: u64, from
: &mut dyn Read
) -> Result
<ObjectId
, crate::write
::Error
> {
149 self.inner
.write_stream(kind
, size
, from
)
153 impl<S
> crate::Find
for Cache
<S
>
157 fn contains(&self, id
: &oid
) -> bool
{
158 self.inner
.contains(id
)
161 fn try_find
<'a
>(&self, id
: &oid
, buffer
: &'a
mut Vec
<u8>) -> Result
<Option
<Data
<'a
>>, crate::find
::Error
> {
162 gix_pack
::Find
::try_find(self, id
, buffer
).map(|t
| t
.map(|t
| t
.0))
166 impl<S
> crate::Header
for Cache
<S
>
170 fn try_header(&self, id
: &oid
) -> Result
<Option
<Header
>, crate::find
::Error
> {
171 self.inner
.try_header(id
)
175 impl<S
> gix_pack
::Find
for Cache
<S
>
179 fn contains(&self, id
: &oid
) -> bool
{
180 self.inner
.contains(id
)
186 buffer
: &'a
mut Vec
<u8>,
187 ) -> Result
<Option
<(Data
<'a
>, Option
<Location
>)>, crate::find
::Error
> {
188 match self.pack_cache
.as_ref().map(RefCell
::borrow_mut
) {
189 Some(mut pack_cache
) => self.try_find_cached(id
, buffer
, pack_cache
.deref_mut()),
190 None
=> self.try_find_cached(id
, buffer
, &mut gix_pack
::cache
::Never
),
194 fn try_find_cached
<'a
>(
197 buffer
: &'a
mut Vec
<u8>,
198 pack_cache
: &mut dyn gix_pack
::cache
::DecodeEntry
,
199 ) -> Result
<Option
<(Data
<'a
>, Option
<gix_pack
::data
::entry
::Location
>)>, crate::find
::Error
> {
200 if let Some(mut obj_cache
) = self.object_cache
.as_ref().map(RefCell
::borrow_mut
) {
201 if let Some(kind
) = obj_cache
.get(&id
.as_ref().to_owned(), buffer
) {
202 return Ok(Some((Data
::new(kind
, buffer
), None
)));
205 let possibly_obj
= self.inner
.try_find_cached(id
.as_ref(), buffer
, pack_cache
)?
;
206 if let (Some(mut obj_cache
), Some((obj
, _location
))) =
207 (self.object_cache
.as_ref().map(RefCell
::borrow_mut
), &possibly_obj
)
209 obj_cache
.put(id
.as_ref().to_owned(), obj
.kind
, obj
.data
);
214 fn location_by_oid(&self, id
: &oid
, buf
: &mut Vec
<u8>) -> Option
<gix_pack
::data
::entry
::Location
> {
215 self.inner
.location_by_oid(id
, buf
)
218 fn pack_offsets_and_oid(&self, pack_id
: u32) -> Option
<Vec
<(u64, gix_hash
::ObjectId
)>> {
219 self.inner
.pack_offsets_and_oid(pack_id
)
222 fn entry_by_location(&self, location
: &Location
) -> Option
<gix_pack
::find
::Entry
> {
223 self.inner
.entry_by_location(location
)