@@ -50,29 +50,74 @@ impl KamtFactory {
50
50
fn test_basics ( factory : KamtFactory ) {
51
51
let store = MemoryBlockstore :: default ( ) ;
52
52
let mut kamt: HKamt < _ , _ > = factory. new ( & store) ;
53
- kamt. set ( 1 , "world" . to_string ( ) ) . unwrap ( ) ;
54
53
54
+ kamt. set ( 1 , "world" . to_string ( ) ) . unwrap ( ) ;
55
55
assert_eq ! ( kamt. get( & 1 ) . unwrap( ) , Some ( & "world" . to_string( ) ) ) ;
56
+ assert ! ( kamt. contains_key( & 1 ) . unwrap( ) ) ;
57
+
56
58
kamt. set ( 1 , "world2" . to_string ( ) ) . unwrap ( ) ;
57
59
assert_eq ! ( kamt. get( & 1 ) . unwrap( ) , Some ( & "world2" . to_string( ) ) ) ;
60
+ assert ! ( kamt. contains_key( & 1 ) . unwrap( ) ) ;
61
+
62
+ assert_eq ! ( kamt. get( & 2 ) . unwrap( ) , None ) ;
63
+ assert ! ( !kamt. contains_key( & 2 ) . unwrap( ) ) ;
58
64
}
59
65
60
66
fn test_n_keys ( factory : KamtFactory ) {
67
+ const KEY_LEN : usize = 32 ;
61
68
let store = MemoryBlockstore :: default ( ) ;
62
69
// Test increasing numbers of sequential keys.
63
- for i in 0u8 ..=255 {
64
- let mut kamt: HKamt < _ , _ , _ > = factory. new ( & store) ;
65
- for j in 0 ..i {
66
- let mut k = [ 0 ; 32 ] ;
67
- k[ 31 ] = j;
68
- kamt. set ( k, format ! ( "{i}" ) ) . unwrap ( ) ;
70
+ fn key ( j : u64 ) -> [ u8 ; KEY_LEN ] {
71
+ let mut k = [ 0 ; KEY_LEN ] ;
72
+ let encoded = j. to_be_bytes ( ) ;
73
+ k[ ( KEY_LEN - encoded. len ( ) ) ..] . copy_from_slice ( & encoded[ ..] ) ;
74
+ k
75
+ }
76
+
77
+ for do_flush in [ true , false ] {
78
+ for i in 0 ..=300 {
79
+ let mut kamt: HKamt < _ , _ , _ > = factory. new ( & store) ;
80
+ let k_too_big = key ( i + 1 ) ;
81
+ for j in 0 ..i {
82
+ // Maybe try flushing/reloading (clearing the cache and/or dirty bits).
83
+ if do_flush {
84
+ if j == i / 3 {
85
+ // Flush but don't reload.
86
+ kamt. flush ( ) . unwrap ( ) ;
87
+ } else if j == ( 2 * i) / 3 {
88
+ // Flush and reload.
89
+ let new_root = kamt. flush ( ) . unwrap ( ) ;
90
+ kamt. set_root ( & new_root) . unwrap ( ) ;
91
+ }
92
+ }
93
+
94
+ let k = key ( j) ;
95
+ kamt. set ( k, format ! ( "{j}" ) ) . unwrap ( ) ;
96
+ }
97
+
98
+ // Fail to get an item out of range.
99
+ assert_eq ! ( kamt. get( & k_too_big) . unwrap( ) , None ) ;
100
+
101
+ // Make sure we get what we expect after reloading.
102
+ let root = kamt. flush ( ) . unwrap ( ) ;
103
+ let new_kamt = factory. load ( & root, & store) . unwrap ( ) ;
104
+ assert_eq ! ( kamt, new_kamt) ;
105
+
106
+ // And the items are the same.
107
+ let old_items = kamt. iter ( ) . collect :: < Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
108
+ let new_items = new_kamt. iter ( ) . collect :: < Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
109
+ assert_eq ! ( old_items, new_items) ;
110
+
111
+ // And we still fail to get an item out of range.
112
+ assert_eq ! ( new_kamt. get( & k_too_big) . unwrap( ) , None ) ;
113
+
114
+ // Assert we can independently look up every key when load a fresh hamt.
115
+ for j in 0 ..i {
116
+ let kamt: HKamt < _ , _ , [ u8 ; KEY_LEN ] > = factory. load ( & root, & store) . unwrap ( ) ;
117
+ let k = key ( j) ;
118
+ assert_eq ! ( kamt. get( & k) . unwrap( ) , Some ( & format!( "{j}" ) ) ) ;
119
+ }
69
120
}
70
- let root = kamt. flush ( ) . unwrap ( ) ;
71
- let new_kamt = factory. load ( & root, & store) . unwrap ( ) ;
72
- assert_eq ! ( kamt, new_kamt) ;
73
- let old_items = kamt. iter ( ) . collect :: < Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
74
- let new_items = new_kamt. iter ( ) . collect :: < Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
75
- assert_eq ! ( old_items, new_items) ;
76
121
}
77
122
}
78
123
@@ -200,12 +245,13 @@ fn for_each(factory: KamtFactory) {
200
245
201
246
let c = kamt. flush ( ) . unwrap ( ) ;
202
247
203
- let kamt: HKamt < _ , i32 , u16 > = factory. load ( & c, & store) . unwrap ( ) ;
248
+ let mut kamt: HKamt < _ , i32 , u16 > = factory. load ( & c, & store) . unwrap ( ) ;
204
249
205
250
// Iterating through kamt with no cache.
206
251
let mut sum = 0 ;
207
252
#[ allow( deprecated) ]
208
- kamt. for_each ( |_, v| {
253
+ kamt. for_each ( |& k, & v| {
254
+ assert_eq ! ( k as i32 , v) ;
209
255
sum += v;
210
256
Ok ( ( ) )
211
257
} )
@@ -215,12 +261,33 @@ fn for_each(factory: KamtFactory) {
215
261
// Iterating through kamt with cached nodes.
216
262
let mut sum = 0 ;
217
263
#[ allow( deprecated) ]
218
- kamt. for_each ( |_, v| {
264
+ kamt. for_each ( |& k, & v| {
265
+ assert_eq ! ( k as i32 , v) ;
219
266
sum += v;
220
267
Ok ( ( ) )
221
268
} )
222
269
. unwrap ( ) ;
223
270
assert_eq ! ( sum, expected_sum) ;
271
+
272
+ // Iterate with a few modified nodes.
273
+ kamt. set ( 10 , 11 ) . unwrap ( ) ;
274
+ kamt. set ( 80 , 83 ) . unwrap ( ) ;
275
+ kamt. set ( 81 , 85 ) . unwrap ( ) ;
276
+ assert_eq ! ( kamt. delete( & 30 ) . unwrap( ) , Some ( 30 ) ) ;
277
+
278
+ // Delete a non-existent value because why not!
279
+ assert ! ( kamt. delete( & 900 ) . unwrap( ) . is_none( ) ) ;
280
+
281
+ #[ allow( deprecated) ]
282
+ let mut sum = 0 ;
283
+ kamt. for_each ( |& k, v| {
284
+ assert_ne ! ( k, 30 ) ; // should be deleted.
285
+ sum += v;
286
+ Ok ( ( ) )
287
+ } )
288
+ . unwrap ( ) ;
289
+
290
+ assert_eq ! ( sum, expected_sum + 1 + 3 + 4 - 30 ) ;
224
291
}
225
292
226
293
/// List of key value pairs with unique keys.
0 commit comments