@@ -19,18 +19,19 @@ use crate::{
1919 value:: InternalValue ,
2020 version:: Version ,
2121 vlog:: { Accessor , BlobFile , BlobFileWriter , ValueHandle } ,
22- Config , Memtable , SeqNo , SequenceNumberCounter , TableId , UserKey , UserValue ,
22+ Cache , Config , DescriptorTable , Memtable , SeqNo , SequenceNumberCounter , TableId , TreeId ,
23+ UserKey , UserValue ,
2324} ;
2425use handle:: BlobIndirection ;
2526use std:: { io:: Cursor , ops:: RangeBounds , path:: PathBuf , sync:: Arc } ;
2627
27- pub struct Guard < ' a > {
28- blob_tree : & ' a BlobTree ,
28+ pub struct Guard {
29+ tree : crate :: BlobTree ,
2930 version : Version ,
3031 kv : crate :: Result < InternalValue > ,
3132}
3233
33- impl IterGuard for Guard < ' _ > {
34+ impl IterGuard for Guard {
3435 fn key ( self ) -> crate :: Result < UserKey > {
3536 self . kv . map ( |kv| kv. key . user_key )
3637 }
@@ -48,23 +49,37 @@ impl IterGuard for Guard<'_> {
4849 }
4950
5051 fn into_inner ( self ) -> crate :: Result < ( UserKey , UserValue ) > {
51- resolve_value_handle ( self . blob_tree , & self . version , self . kv ?)
52+ resolve_value_handle (
53+ self . tree . id ( ) ,
54+ self . tree . blobs_folder . as_path ( ) ,
55+ & self . tree . index . config . cache ,
56+ & self . tree . index . config . descriptor_table ,
57+ & self . version ,
58+ self . kv ?,
59+ )
5260 }
5361}
5462
55- fn resolve_value_handle ( tree : & BlobTree , version : & Version , item : InternalValue ) -> RangeItem {
63+ fn resolve_value_handle (
64+ tree_id : TreeId ,
65+ blobs_folder : & std:: path:: Path ,
66+ cache : & Arc < Cache > ,
67+ descriptor_table : & Arc < DescriptorTable > ,
68+ version : & Version ,
69+ item : InternalValue ,
70+ ) -> RangeItem {
5671 if item. key . value_type . is_indirection ( ) {
5772 let mut cursor = Cursor :: new ( item. value ) ;
5873 let vptr = BlobIndirection :: decode_from ( & mut cursor) ?;
5974
6075 // Resolve indirection using value log
6176 match Accessor :: new ( & version. blob_files ) . get (
62- tree . id ( ) ,
63- & tree . blobs_folder ,
77+ tree_id ,
78+ blobs_folder,
6479 & item. key . user_key ,
6580 & vptr. vhandle ,
66- & tree . index . config . cache ,
67- & tree . index . config . descriptor_table ,
81+ cache,
82+ descriptor_table,
6883 ) {
6984 Ok ( Some ( v) ) => {
7085 let k = item. key . user_key ;
@@ -97,7 +112,7 @@ pub struct BlobTree {
97112 #[ doc( hidden) ]
98113 pub index : crate :: Tree ,
99114
100- blobs_folder : PathBuf ,
115+ blobs_folder : Arc < PathBuf > ,
101116}
102117
103118impl BlobTree {
@@ -123,7 +138,7 @@ impl BlobTree {
123138
124139 Ok ( Self {
125140 index,
126- blobs_folder,
141+ blobs_folder : Arc :: new ( blobs_folder ) ,
127142 } )
128143 }
129144}
@@ -179,20 +194,20 @@ impl AbstractTree for BlobTree {
179194 prefix : K ,
180195 seqno : SeqNo ,
181196 index : Option < Arc < Memtable > > ,
182- ) -> Box < dyn DoubleEndedIterator < Item = IterGuardImpl < ' _ > > + ' _ > {
197+ ) -> Box < dyn DoubleEndedIterator < Item = IterGuardImpl > + Send + ' static > {
183198 use crate :: range:: prefix_to_range;
184199
185200 let range = prefix_to_range ( prefix. as_ref ( ) ) ;
186-
187201 let version = self . current_version ( ) ;
202+ let tree = self . clone ( ) ;
188203
189204 Box :: new (
190205 self . index
191206 . create_internal_range ( & range, seqno, index)
192207 . map ( move |kv| {
193208 IterGuardImpl :: Blob ( Guard {
194- blob_tree : self ,
195- version : version. clone ( ) , // TODO: PERF: ugly Arc clone
209+ tree : tree . clone ( ) ,
210+ version : version. clone ( ) ,
196211 kv,
197212 } )
198213 } ) ,
@@ -204,17 +219,17 @@ impl AbstractTree for BlobTree {
204219 range : R ,
205220 seqno : SeqNo ,
206221 index : Option < Arc < Memtable > > ,
207- ) -> Box < dyn DoubleEndedIterator < Item = IterGuardImpl < ' _ > > + ' _ > {
222+ ) -> Box < dyn DoubleEndedIterator < Item = IterGuardImpl > + Send + ' static > {
208223 let version = self . current_version ( ) ;
224+ let tree = self . clone ( ) ;
209225
210- // TODO: PERF: ugly Arc clone
211226 Box :: new (
212227 self . index
213228 . create_internal_range ( & range, seqno, index)
214229 . map ( move |kv| {
215230 IterGuardImpl :: Blob ( Guard {
216- blob_tree : self ,
217- version : version. clone ( ) , // TODO: PERF: ugly Arc clone
231+ tree : tree . clone ( ) ,
232+ version : version. clone ( ) ,
218233 kv,
219234 } )
220235 } ) ,
@@ -647,7 +662,14 @@ impl AbstractTree for BlobTree {
647662 } ;
648663
649664 let version = self . current_version ( ) ;
650- let ( _, v) = resolve_value_handle ( self , & version, item) ?;
665+ let ( _, v) = resolve_value_handle (
666+ self . id ( ) ,
667+ self . blobs_folder . as_path ( ) ,
668+ & self . index . config . cache ,
669+ & self . index . config . descriptor_table ,
670+ & version,
671+ item,
672+ ) ?;
651673
652674 Ok ( Some ( v) )
653675 }
0 commit comments