4444 H : CHasher ,
4545{
4646 /// Authenticated journal batch for computing the speculative Merkle root.
47- journal_batch : authenticated:: UnmerkleizedBatch < F , H , Operation < K , V > > ,
47+ journal_batch : authenticated:: UnmerkleizedBatch < F , H , Operation < F , K , V > > ,
4848
4949 /// Pending mutations.
5050 mutations : BTreeMap < K , V :: Value > ,
6565#[ derive( Clone ) ]
6666pub struct MerkleizedBatch < F : Family , D : Digest , K : Key , V : ValueEncoding > {
6767 /// Authenticated journal batch (Merkle state + local items).
68- pub ( super ) journal_batch : Arc < authenticated:: MerkleizedBatch < F , D , Operation < K , V > > > ,
68+ pub ( super ) journal_batch : Arc < authenticated:: MerkleizedBatch < F , D , Operation < F , K , V > > > ,
6969
7070 /// This batch's local key-level changes only (not accumulated from ancestors).
7171 /// Sorted by key with no duplicates; queried via `lookup_sorted` (binary search).
@@ -92,6 +92,9 @@ pub struct MerkleizedBatch<F: Family, D: Digest, K: Key, V: ValueEncoding> {
9292 /// 1:1 with `ancestor_diffs`: `ancestor_diff_ends[i]` is the boundary for
9393 /// `ancestor_diffs[i]`. A batch is committed when `ancestor_diff_ends[i] <= db_size`.
9494 pub ( super ) ancestor_diff_ends : Vec < u64 > ,
95+
96+ /// The inactivity floor declared by this batch's commit operation.
97+ pub ( super ) new_inactivity_floor_loc : Location < F > ,
9598}
9699
97100impl < F , H , K , V > UnmerkleizedBatch < F , H , K , V >
@@ -100,7 +103,7 @@ where
100103 K : Key ,
101104 V : ValueEncoding ,
102105 H : CHasher ,
103- Operation < K , V > : EncodeShared ,
106+ Operation < F , K , V > : EncodeShared ,
104107{
105108 /// Create a batch from a committed DB (no parent chain).
106109 pub ( super ) fn new < E , C , T > (
@@ -109,7 +112,7 @@ where
109112 ) -> Self
110113 where
111114 E : Context ,
112- C : Mutable < Item = Operation < K , V > > + Persistable < Error = JournalError > ,
115+ C : Mutable < Item = Operation < F , K , V > > + Persistable < Error = JournalError > ,
113116 C :: Item : EncodeShared ,
114117 T : Translator ,
115118 {
@@ -139,7 +142,7 @@ where
139142 ) -> Result < Option < V :: Value > , Error < F > >
140143 where
141144 E : Context ,
142- C : Mutable < Item = Operation < K , V > > + Persistable < Error = JournalError > ,
145+ C : Mutable < Item = Operation < F , K , V > > + Persistable < Error = JournalError > ,
143146 C :: Item : EncodeShared ,
144147 T : Translator ,
145148 {
@@ -164,22 +167,26 @@ where
164167 }
165168
166169 /// Resolve mutations into operations, merkleize, and return an `Arc<MerkleizedBatch>`.
170+ ///
171+ /// `inactivity_floor` declares that all operations before this location are inactive.
172+ /// It must be >= the database's current inactivity floor (monotonically non-decreasing).
167173 pub fn merkleize < E , C , T > (
168174 self ,
169175 db : & Immutable < F , E , K , V , C , H , T > ,
170176 metadata : Option < V :: Value > ,
177+ inactivity_floor : Location < F > ,
171178 ) -> Arc < MerkleizedBatch < F , H :: Digest , K , V > >
172179 where
173180 E : Context ,
174- C : Mutable < Item = Operation < K , V > > + Persistable < Error = JournalError > ,
181+ C : Mutable < Item = Operation < F , K , V > > + Persistable < Error = JournalError > ,
175182 C :: Item : EncodeShared ,
176183 T : Translator ,
177184 {
178185 let base = self . base_size ;
179186
180187 // Build operations: one Set per key, then Commit. `self.mutations` is a BTreeMap, so
181188 // iteration yields keys in sorted order, which `diff` relies on for binary search.
182- let mut ops: Vec < Operation < K , V > > = Vec :: with_capacity ( self . mutations . len ( ) + 1 ) ;
189+ let mut ops: Vec < Operation < F , K , V > > = Vec :: with_capacity ( self . mutations . len ( ) + 1 ) ;
183190 let mut diff: DiffVec < K , F , V :: Value > = Vec :: with_capacity ( self . mutations . len ( ) ) ;
184191
185192 for ( key, value) in self . mutations {
@@ -189,7 +196,7 @@ where
189196 }
190197 debug_assert ! ( diff. is_sorted_by( |a, b| a. 0 < b. 0 ) ) ;
191198
192- ops. push ( Operation :: Commit ( metadata) ) ;
199+ ops. push ( Operation :: Commit ( metadata, inactivity_floor ) ) ;
193200
194201 let total_size = base + ops. len ( ) as u64 ;
195202
@@ -220,13 +227,14 @@ where
220227 db_size : self . db_size ,
221228 ancestor_diffs,
222229 ancestor_diff_ends,
230+ new_inactivity_floor_loc : inactivity_floor,
223231 } )
224232 }
225233}
226234
227235impl < F : Family , D : Digest , K : Key , V : ValueEncoding > MerkleizedBatch < F , D , K , V >
228236where
229- Operation < K , V > : EncodeShared ,
237+ Operation < F , K , V > : EncodeShared ,
230238{
231239 /// Return the speculative root.
232240 pub fn root ( & self ) -> D {
@@ -251,7 +259,7 @@ where
251259 ) -> Result < Option < V :: Value > , Error < F > >
252260 where
253261 E : Context ,
254- C : Mutable < Item = Operation < K , V > > + Persistable < Error = JournalError > ,
262+ C : Mutable < Item = Operation < F , K , V > > + Persistable < Error = JournalError > ,
255263 C :: Item : EncodeShared ,
256264 H : CHasher < Digest = D > ,
257265 T : Translator ,
@@ -292,7 +300,7 @@ where
292300 E : Context ,
293301 K : Key ,
294302 V : ValueEncoding ,
295- C : Mutable < Item = Operation < K , V > > + Persistable < Error = JournalError > ,
303+ C : Mutable < Item = Operation < F , K , V > > + Persistable < Error = JournalError > ,
296304 C :: Item : EncodeShared ,
297305 H : CHasher ,
298306 T : Translator ,
@@ -309,6 +317,7 @@ where
309317 db_size : journal_size,
310318 ancestor_diffs : Vec :: new ( ) ,
311319 ancestor_diff_ends : Vec :: new ( ) ,
320+ new_inactivity_floor_loc : self . inactivity_floor_loc ,
312321 } )
313322 }
314323}
0 commit comments