More efficient free list: avoid extending the file when updating the list of free pages
Dependencies
- [2]
RLVQDUPYFixing a double-free error introduced in 1.2.13 - [3]
E4MD6T3LProofreading and commenting of this crate (massive bug fixes included) - [4]
OP6SVMODResetting history - [5]
OHG5NX6KRefactoring, drop and the Check trait
Change contents
- replacement in sanakirja/src/environment/muttxn.rs at line 267[3.9333]→[2.1345:1712](∅→∅),[2.1712]→[3.9590:9666](∅→∅),[3.9590]→[3.9590:9666](∅→∅),[3.9666]→[2.1713:1893](∅→∅)
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; - edit in sanakirja/src/environment/muttxn.rs at line 278
} - replacement in sanakirja/src/environment/muttxn.rs at line 279[3.9685]→[3.11580:11879](∅→∅),[3.11580]→[3.11580:11879](∅→∅),[3.12459]→[3.12459:12656](∅→∅),[3.12656]→[2.1916:1974](∅→∅),[2.1974]→[3.12656:12735](∅→∅),[3.12656]→[3.12656:12735](∅→∅),[3.12735]→[2.1975:2167](∅→∅)
// 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; - replacement in sanakirja/src/environment/muttxn.rs at line 289[2.2193]→[3.12735:12871](∅→∅),[3.12735]→[3.12735:12871](∅→∅),[3.12871]→[2.2194:2258](∅→∅),[2.2258]→[3.12871:12950](∅→∅),[3.12871]→[3.12871:12950](∅→∅),[3.12950]→[2.2259:2451](∅→∅)
}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; - edit in sanakirja/src/environment/muttxn.rs at line 297
// 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;}}