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