5NBCUZRB6HQHE4CMVI4QJKXNBYON5OGOVGAOJPDV3WGJVVQ55UKAC
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);
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;
let mut changed = true;
// Fix point on the freed and allocated pages.
while changed {
changed = false;
// 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() {
btree::del(&mut self, &mut free_db, &p.to_le(), None)?;
changed = true;
// Adding all the pages freed during the transaction to the
// tree of free pages. If this call to `btree::put` frees
// pages, add them again. This converges in at most log n
// iterations (where n is the total number of free pages).
while !self.free_pages.is_empty() || !self.free_owned_pages.is_empty() {
while let Some(p) = self.free_pages.pop() {
let p = p & !0xfff;
debug!("put free {} {:x}", n, p);
btree::put(&mut self, &mut free_db, &p.to_le(), &())?;
if cfg!(debug_assertions) {
crate::debug::debug(&self, &[&free_db], &format!("/tmp/free_{}", n), true);
n += 1;
// Adding all the pages freed during the transaction to the
// tree of free pages. If this call to `btree::put` frees
// pages, add them again. This converges in at most log n
// iterations (where n is the total number of free pages).
while !self.free_pages.is_empty() || !self.free_owned_pages.is_empty() {
while let Some(p) = self.free_pages.pop() {
let p = p & !0xfff;
btree::put(&mut self, &mut free_db, &p.to_le(), &())?;
changed = true;
}
while let Some(p) = self.free_owned_pages.pop() {
let p = p & !0xfff;
debug!("put owned free {} {:x}", n, p);
btree::put(&mut self, &mut free_db, &p.to_le(), &())?;
if cfg!(debug_assertions) {
crate::debug::debug(&self, &[&free_db], &format!("/tmp/free_{}", n), true);
n += 1;
while let Some(p) = self.free_owned_pages.pop() {
let p = p & !0xfff;
btree::put(&mut self, &mut free_db, &p.to_le(), &())?;
changed = true;
// 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;
}
}