RLVQDUPYOWVNHTVFCHKNIQYNBRLOFY2UGIJPLD6U5S22AMEF5YSAC
OHG5NX6KVGKNA7S7SU3MTPOZCN4RRZK2SGZWZ5LIRXUMCYIPUHIAC
OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC
3QM7P3RRVYYDEJNFDG3GHZDMSSHPPJC3WQOJGETGREOM4I2A6D5AC
E4MD6T3LNOYWVFTFFWCUKRNS4M2XVSKRLDWPYHMZHGDNO2T5JREQC
YWFYZNLZ5JHLIFVBRKZK4TSWVPROUPRG77ZB5M7UHT2OKPL4ZSRQC
T7QB6QEPWBXAU3RL7LE4GRDWWNQ65ZU2YNNTWBYLORJOABAQFEZQC
4Z4GEJTFQFYDOJK3D72LKOFSC5Q42SNL3N6UOYCYW5FXCA67G66AC
OHUZ73MKWD7SSB4DKKA532DEQKXQDS6PZ6HJ3EC2DLVJSLQH3NLAC
YXKP4AIWDBIWBBUDWF66YIPG5ECMHNKEV3PX6KYXOVXY3EWG3WGQC
ACB4A27ZMFLRLDAKFRSGAFJRESN3UCVFADQPYCK7TGAIJMSG3FHQC
/// Offsets of pages free at the start of the transaction.
initial_free: (usize, Vec<u64>),
/// Offsets of pages that were free at the start of the
/// transaction, and are still free.
initial_free: Vec<u64>,
/// Offsets of pages that were free at the start of the
/// transaction, but have been allocated since then.
initial_allocated: Vec<u64>,
{
for p in btree::iter(&self, &free_db, None).unwrap() {
debug!("was free: p = {:x}", p.unwrap().0);
if cfg!(debug_assertions) {
// Deleting the pages allocated during this
// transaction from the free db. Note that the call to
// `del` may add pages to `self.initial_allocated`.
for p in self.initial_free.iter() {
debug!("initial_free {:x}", p);
// Deleting the pages allocated during this transaction.
let mut f = self.initial_free.1.len();
while f > self.initial_free.0 {
f -= 1;
let p = self.initial_free.1[f];
let mut n = 0;
// Delete the pages allocated during this transaction
// from the free db. If these pages have been freed
// again, they will be reinserted below.
while let Some(p) = self.initial_allocated.pop() {
debug!("del initial {} {:x} {:x}", n, free_db.db, p);
// Delete the pages allocated during in the calls to
// `put` just above. Note that this is the same code
// as just before the `put`s. We need this duplication
// because doing this only here could potentially
// delete pages we just inserted, causing leaks.
//
// Conversely, doing it only above could result in
// pages being allocated in the calls to `put` above,
// and still counted as free.
while let Some(p) = self.initial_allocated.pop() {
debug!("del initial {} {:x} {:x}", n, free_db.db, p);
btree::del(&mut self, &mut free_db, &p.to_le(), None)?;
if cfg!(debug_assertions) {
crate::debug::debug(&self, &[&free_db], &format!("/tmp/free_{}", n), true);
n += 1;
}
}
while self.initial_free.0 > 0 {
self.initial_free.0 -= 1;
let f = self.initial_free.1[self.initial_free.0];
if self.free_for_all(f)? {
return Ok(Some(f));
while let Some(p) = self.initial_free.pop() {
if self.free_for_all(p)? {
self.initial_allocated.push(p);
return Ok(Some(p));