// Checkpoint accomplishes freeing of slots that are no longer required.
// All the slots that ever were overwritten are tracked in the gc lists.
// These slots cannot be unilaterally freed as they might still be
// referred by older rounds. Current implementation just deletes all
// previous rounds there by keeping the problem simple.
// Alternatively we can find out the oldest round on which query might be
// progressing All rounds older than that can free all the slots that were
// overwritten in the later rounds. Find such slots and then mark them as
// free. If all slots from the gc table are freed in such a way empty that
// table.
Checkpoint accomplishes freeing of slots that are no longer required.
All the slots that ever were overwritten are tracked in the gc lists.
These slots cannot be unilaterally freed as they might still be
referred by older rounds. Current implementation just deletes all
previous rounds there by keeping the problem simple.
Alternatively we can find out the oldest round on which query might be
progressing All rounds older than that can free all the slots that were
overwritten in the later rounds. Find such slots and then mark them as
free. If all slots from the gc table are freed in such a way empty that
table.
Checkpoint accomplishes freeing of slots that are no longer required . All the slots that ever were overwritten are tracked in the gc lists . These slots cannot be unilaterally freed as they might still be referred by older rounds . Current implementation just deletes all previous rounds there by keeping the problem simple . Alternatively we can find out the oldest round on which query might be progressing All rounds older than that can free all the slots that were overwritten in the later rounds . Find such slots and then mark them as free . If all slots from the gc table are freed in such a way empty that table .
pub fn remove_rounds_below(&self, max_to_keep: u64) {
        let mut free_slot_list = HashSet::new();
        let mut rounds = Vec::new();
        // Find rounds to delete
        reading(self, "SlotMgr::remove_rounds_below", |ro_txn| {
            let mut ro_cursor = ro_txn.open_ro_cursor(self.completed_rounds).unwrap();
            for (round, _) in ro_cursor.iter().map(Result::unwrap) {
                let round = Self::decode_u64(round);
                if round < max_to_keep {
                    rounds.push(round);
                }
            }
            // Get all the slots that can be gced
            let mut ro_cursor = ro_txn.open_ro_cursor(self.slots_to_gc).unwrap();
            for (rawk, dropped_at_round) in ro_cursor.iter().map(Result::unwrap) {
                let slot = Self::decode_u64(rawk);
                let dropped_at_round = Self::decode_u64(dropped_at_round);
                if dropped_at_round < max_to_keep {
                    free_slot_list.insert(slot);
                }
            }
        });
        // Add the gc candidate slots to the free list for future allocation
        writing(self, "SlotMgr::remove_rounds_below", |rw_txn| {
            for free_blk in free_slot_list {
                rw_txn
                    .put(
                        self.free_list_table,
                        &free_blk.to_le_bytes(),
                        &1_u64.to_le_bytes(),
                        WriteFlags::NO_DUP_DATA,
                    )
                    .expect("put failed");
            }
            // drop the round specific mappings
            for round in rounds {
                RoundDb::drop(rw_txn, round);
                rw_txn
                    .del(self.completed_rounds, &round.to_le_bytes(), None)
                    .expect("deleting from the completed rounds")
            }
        });
        // Flush everything out that was lying around in memory is flushed to disk
        self.sync();
    }
pub fn remove_rounds_below ( & self , max_to_keep : u64 ) { let mut free_slot_list = HashSet :: new ( ) ; let mut rounds = Vec :: new ( ) ; // Find rounds to delete reading ( self , " " , | ro_txn | { let mut ro_cursor = ro_txn . open_ro_cursor ( self . completed_rounds ) . unwrap ( ) ; for ( round , _ ) in ro_cursor . iter ( ) . map ( Result :: unwrap ) { let round = Self :: decode_u64 ( round ) ; if round < max_to_keep { rounds . push ( round ) ; } } // Get all the slots that can be gced let mut ro_cursor = ro_txn . open_ro_cursor ( self . slots_to_gc ) . unwrap ( ) ; for ( rawk , dropped_at_round ) in ro_cursor . iter ( ) . map ( Result :: unwrap ) { let slot = Self :: decode_u64 ( rawk ) ; let dropped_at_round = Self :: decode_u64 ( dropped_at_round ) ; if dropped_at_round < max_to_keep { free_slot_list . insert ( slot ) ; } } } ) ; // Add the gc candidate slots to the free list for future allocation writing ( self , " " , | rw_txn | { for free_blk in free_slot_list { rw_txn . put ( self . free_list_table , & free_blk . to_le_bytes ( ) , & 1_u64 . to_le_bytes ( ) , WriteFlags :: NO_DUP_DATA , ) . expect ( " " ) ; } // drop the round specific mappings for round in rounds { RoundDb :: drop ( rw_txn , round ) ; rw_txn . del ( self . completed_rounds , & round . to_le_bytes ( ) , None ) . expect ( " " ) } } ) ; // Flush everything out that was lying around in memory is flushed to disk self . sync ( ) ; }
Checkpoint accomplishes freeing of slots that are no longer required.
Checkpoint accomplishes freeing of slots that are no longer required .
&self
max_to_keep
u64