11// Copyright 2021-2023 Protocol Labs 
22// SPDX-License-Identifier: Apache-2.0, MIT 
33use  std:: borrow:: Borrow ; 
4+ use  std:: fmt:: Display ; 
45use  std:: iter:: FusedIterator ; 
56
67use  forest_hash_utils:: BytesKey ; 
@@ -17,8 +18,8 @@ use crate::{Config, Error, Hash, HashAlgorithm, KeyValuePair, Sha256};
1718pub  struct  IterImpl < ' a ,  BS ,  V ,  K  = BytesKey ,  H  = Sha256 ,  Ver  = version:: V3 >  { 
1819    store :  & ' a  BS , 
1920    conf :  & ' a  Config , 
20-     stack :  Vec < std :: slice :: Iter < ' a ,  Pointer < K ,  V ,  H ,  Ver > > > , 
21-     current :  std :: slice :: Iter < ' a ,  KeyValuePair < K ,  V > > , 
21+     stack :  Vec < StackItem < ' a ,  Pointer < K ,  V ,  H ,  Ver > > > , 
22+     current :  StackItem < ' a ,  KeyValuePair < K ,  V > > , 
2223} 
2324
2425/// Iterator over HAMT Key/Value tuples (hamt v0). 
@@ -27,19 +28,90 @@ pub type Iterv0<'a, BS, V, K = BytesKey, H = Sha256> = IterImpl<'a, BS, V, K, H,
2728/// Iterator over HAMT Key/Value tuples. 
2829pub  type  Iter < ' a ,  BS ,  V ,  K  = BytesKey ,  H  = Sha256 >  = IterImpl < ' a ,  BS ,  V ,  K ,  H ,  version:: V3 > ; 
2930
31+ enum  StackItem < ' a ,  V >  { 
32+     Iter ( std:: slice:: Iter < ' a ,  V > ) , 
33+     IntoIter ( std:: vec:: IntoIter < V > ) , 
34+ } 
35+ 
36+ impl < ' a ,  V >  From < std:: slice:: Iter < ' a ,  V > >  for  StackItem < ' a ,  V >  { 
37+     fn  from ( value :  std:: slice:: Iter < ' a ,  V > )  -> Self  { 
38+         Self :: Iter ( value) 
39+     } 
40+ } 
41+ 
42+ impl < ' a ,  V >  From < std:: vec:: IntoIter < V > >  for  StackItem < ' a ,  V >  { 
43+     fn  from ( value :  std:: vec:: IntoIter < V > )  -> Self  { 
44+         Self :: IntoIter ( value) 
45+     } 
46+ } 
47+ 
48+ impl < ' a ,  V >  Iterator  for  StackItem < ' a ,  V >  { 
49+     type  Item  = IterItem < ' a ,  V > ; 
50+ 
51+     fn  next ( & mut  self )  -> Option < Self :: Item >  { 
52+         match  self  { 
53+             Self :: Iter ( it)  => it. next ( ) . map ( |i| i. into ( ) ) , 
54+             Self :: IntoIter ( it)  => it. next ( ) . map ( |i| i. into ( ) ) , 
55+         } 
56+     } 
57+ } 
58+ 
59+ #[ derive( Debug ,  Clone ,  PartialEq ,  Eq ,  PartialOrd ,  Ord ) ]  
60+ pub  enum  IterItem < ' a ,  V >  { 
61+     Borrowed ( & ' a  V ) , 
62+     Owned ( V ) , 
63+ } 
64+ 
65+ impl < V :  Display >  Display  for  IterItem < ' _ ,  V >  { 
66+     fn  fmt ( & self ,  f :  & mut  std:: fmt:: Formatter < ' _ > )  -> std:: fmt:: Result  { 
67+         self . as_ref ( ) . fmt ( f) 
68+     } 
69+ } 
70+ 
71+ impl < V >  AsRef < V >  for  IterItem < ' _ ,  V >  { 
72+     fn  as_ref ( & self )  -> & V  { 
73+         match  self  { 
74+             Self :: Borrowed ( v)  => v, 
75+             Self :: Owned ( v)  => v, 
76+         } 
77+     } 
78+ } 
79+ 
80+ impl < V :  PartialEq >  PartialEq < V >  for  IterItem < ' _ ,  V >  { 
81+     fn  eq ( & self ,  other :  & V )  -> bool  { 
82+         self . as_ref ( ) . eq ( other) 
83+     } 
84+ 
85+     fn  ne ( & self ,  other :  & V )  -> bool  { 
86+         self . as_ref ( ) . ne ( other) 
87+     } 
88+ } 
89+ 
90+ impl < ' a ,  V >  From < V >  for  IterItem < ' a ,  V >  { 
91+     fn  from ( value :  V )  -> Self  { 
92+         Self :: Owned ( value) 
93+     } 
94+ } 
95+ 
96+ impl < ' a ,  V >  From < & ' a  V >  for  IterItem < ' a ,  V >  { 
97+     fn  from ( value :  & ' a  V )  -> Self  { 
98+         Self :: Borrowed ( value) 
99+     } 
100+ } 
101+ 
30102impl < ' a ,  K ,  V ,  BS ,  H ,  Ver >  IterImpl < ' a ,  BS ,  V ,  K ,  H ,  Ver > 
31103where 
32-     K :  DeserializeOwned , 
33-     V :  DeserializeOwned , 
104+     K :  DeserializeOwned  +  Clone , 
105+     V :  DeserializeOwned  +  Clone , 
34106    Ver :  Version , 
35107    BS :  Blockstore , 
36108{ 
37109    pub ( crate )  fn  new ( store :  & ' a  BS ,  root :  & ' a  Node < K ,  V ,  H ,  Ver > ,  conf :  & ' a  Config )  -> Self  { 
38110        Self  { 
39111            conf, 
40112            store, 
41-             stack :  vec ! [ root. pointers. iter( ) ] , 
42-             current :  [ ] . iter ( ) , 
113+             stack :  vec ! [ root. pointers. iter( ) . into ( ) ] , 
114+             current :  [ ] . iter ( ) . into ( ) , 
43115        } 
44116    } 
45117
@@ -56,24 +128,52 @@ where
56128    { 
57129        let  hashed_key = H :: hash ( key) ; 
58130        let  mut  hash = HashBits :: new ( & hashed_key) ; 
59-         let  mut  node = root; 
131+         let  mut  node = IterItem :: Borrowed ( root) ; 
60132        let  mut  stack = Vec :: new ( ) ; 
61133        loop  { 
62134            let  idx = hash. next ( conf. bit_width ) ?; 
63-             stack. push ( node. pointers [ node. index_for_bit_pos ( idx) ..] . iter ( ) ) ; 
135+             match  node. clone ( )  { 
136+                 IterItem :: Borrowed ( node)  => { 
137+                     stack. push ( StackItem :: from ( 
138+                         node. pointers [ node. index_for_bit_pos ( idx) ..] . iter ( ) , 
139+                     ) ) ; 
140+                 } 
141+                 IterItem :: Owned ( node)  => { 
142+                     stack. push ( StackItem :: from ( 
143+                         node. pointers [ node. index_for_bit_pos ( idx) ..] 
144+                             . to_vec ( ) 
145+                             . into_iter ( ) , 
146+                     ) ) ; 
147+                 } 
148+             } 
64149            node = match  stack. last_mut ( ) . unwrap ( ) . next ( )  { 
65150                Some ( p)  => match  p { 
66-                     Pointer :: Link  {  cid,  cache }  => cache. get_or_try_init ( || { 
67-                         Node :: load ( conf,  store,  cid,  stack. len ( )  as  u32 ) . map ( Box :: new) 
68-                     } ) ?, 
69-                     Pointer :: Dirty ( node)  => node, 
70-                     Pointer :: Values ( values)  => { 
151+                     IterItem :: Borrowed ( Pointer :: Link  {  cid,  cache :  _ } )  => { 
152+                         Node :: load ( conf,  store,  cid,  stack. len ( )  as  u32 ) ?. into ( ) 
153+                     } 
154+                     IterItem :: Owned ( Pointer :: Link  {  cid,  cache :  _ } )  => { 
155+                         Node :: load ( conf,  store,  & cid,  stack. len ( )  as  u32 ) ?. into ( ) 
156+                     } 
157+                     IterItem :: Borrowed ( Pointer :: Dirty ( node) )  => node. as_ref ( ) . into ( ) , 
158+                     IterItem :: Owned ( Pointer :: Dirty ( node) )  => ( * node) . into ( ) , 
159+                     IterItem :: Borrowed ( Pointer :: Values ( values) )  => { 
160+                         return  match  values. iter ( ) . position ( |kv| kv. key ( ) . borrow ( )  == key)  { 
161+                             Some ( offset)  => Ok ( Self  { 
162+                                 conf, 
163+                                 store, 
164+                                 stack, 
165+                                 current :  values[ offset..] . iter ( ) . into ( ) , 
166+                             } ) , 
167+                             None  => Err ( Error :: StartKeyNotFound ) , 
168+                         } ; 
169+                     } 
170+                     IterItem :: Owned ( Pointer :: Values ( values) )  => { 
71171                        return  match  values. iter ( ) . position ( |kv| kv. key ( ) . borrow ( )  == key)  { 
72172                            Some ( offset)  => Ok ( Self  { 
73173                                conf, 
74174                                store, 
75175                                stack, 
76-                                 current :  values[ offset..] . iter ( ) , 
176+                                 current :  values[ offset..] . to_vec ( ) . into_iter ( ) . into ( ) , 
77177                            } ) , 
78178                            None  => Err ( Error :: StartKeyNotFound ) , 
79179                        } ; 
@@ -92,33 +192,64 @@ where
92192    K :  DeserializeOwned  + PartialOrd , 
93193    V :  DeserializeOwned , 
94194{ 
95-     type  Item  = Result < ( & ' a   K ,   & ' a   V ) ,  Error > ; 
195+     type  Item  = Result < ( IterItem < ' a ,   K > ,   IterItem < ' a ,   V > ) ,  Error > ; 
96196
97197    fn  next ( & mut  self )  -> Option < Self :: Item >  { 
98-         if  let  Some ( v)  = self . current . next ( )  { 
99-             return  Some ( Ok ( ( v. key ( ) ,  v. value ( ) ) ) ) ; 
198+         match  self . current . next ( )  { 
199+             Some ( IterItem :: Borrowed ( v) )  => return  Some ( Ok ( ( v. key ( ) . into ( ) ,  v. value ( ) . into ( ) ) ) ) , 
200+             Some ( IterItem :: Owned ( KeyValuePair ( k,  v) ) )  => return  Some ( Ok ( ( k. into ( ) ,  v. into ( ) ) ) ) , 
201+             _ => { } 
100202        } 
101203        loop  { 
102204            let  Some ( next)  = self . stack . last_mut ( ) ?. next ( )  else  { 
103205                self . stack . pop ( ) ; 
104206                continue ; 
105207            } ; 
106208            match  next { 
107-                 Pointer :: Link  {  cid,  cache }  => { 
108-                     let  node = match  cache. get_or_try_init ( || { 
109-                         Node :: load ( self . conf ,  & self . store ,  cid,  self . stack . len ( )  as  u32 ) 
110-                             . map ( Box :: new) 
111-                     } )  { 
112-                         Ok ( node)  => node, 
113-                         Err ( e)  => return  Some ( Err ( e) ) , 
114-                     } ; 
115-                     self . stack . push ( node. pointers . iter ( ) ) 
209+                 IterItem :: Borrowed ( Pointer :: Link  {  cid,  cache :  _ } )  => { 
210+                     let  node =
211+                         match  Node :: load ( self . conf ,  & self . store ,  cid,  self . stack . len ( )  as  u32 )  { 
212+                             Ok ( node)  => node, 
213+                             Err ( e)  => return  Some ( Err ( e) ) , 
214+                         } ; 
215+                     self . stack . push ( node. pointers . into_iter ( ) . into ( ) ) 
216+                 } 
217+                 IterItem :: Owned ( Pointer :: Link  {  cid,  cache :  _ } )  => { 
218+                     let  node =
219+                         match  Node :: load ( self . conf ,  & self . store ,  & cid,  self . stack . len ( )  as  u32 )  { 
220+                             Ok ( node)  => node, 
221+                             Err ( e)  => return  Some ( Err ( e) ) , 
222+                         } ; 
223+                     self . stack . push ( node. pointers . into_iter ( ) . into ( ) ) 
224+                 } 
225+                 IterItem :: Borrowed ( Pointer :: Dirty ( node) )  => { 
226+                     self . stack . push ( node. pointers . iter ( ) . into ( ) ) 
227+                 } 
228+                 IterItem :: Owned ( Pointer :: Dirty ( node) )  => { 
229+                     self . stack . push ( node. pointers . into_iter ( ) . into ( ) ) 
230+                 } 
231+                 IterItem :: Borrowed ( Pointer :: Values ( kvs) )  => { 
232+                     self . current  = kvs. iter ( ) . into ( ) ; 
233+                     match  self . current . next ( )  { 
234+                         Some ( IterItem :: Borrowed ( v) )  => { 
235+                             return  Some ( Ok ( ( v. key ( ) . into ( ) ,  v. value ( ) . into ( ) ) ) ) ; 
236+                         } 
237+                         Some ( IterItem :: Owned ( KeyValuePair ( k,  v) ) )  => { 
238+                             return  Some ( Ok ( ( k. into ( ) ,  v. into ( ) ) ) ) ; 
239+                         } 
240+                         _ => { } 
241+                     } 
116242                } 
117-                 Pointer :: Dirty ( node)  => self . stack . push ( node. pointers . iter ( ) ) , 
118-                 Pointer :: Values ( kvs)  => { 
119-                     self . current  = kvs. iter ( ) ; 
120-                     if  let  Some ( v)  = self . current . next ( )  { 
121-                         return  Some ( Ok ( ( v. key ( ) ,  v. value ( ) ) ) ) ; 
243+                 IterItem :: Owned ( Pointer :: Values ( kvs) )  => { 
244+                     self . current  = kvs. into_iter ( ) . into ( ) ; 
245+                     match  self . current . next ( )  { 
246+                         Some ( IterItem :: Borrowed ( v) )  => { 
247+                             return  Some ( Ok ( ( v. key ( ) . into ( ) ,  v. value ( ) . into ( ) ) ) ) ; 
248+                         } 
249+                         Some ( IterItem :: Owned ( KeyValuePair ( k,  v) ) )  => { 
250+                             return  Some ( Ok ( ( k. into ( ) ,  v. into ( ) ) ) ) ; 
251+                         } 
252+                         _ => { } 
122253                    } 
123254                } 
124255            } 
0 commit comments