implement general allocator
This commit is contained in:
parent
2d9791db30
commit
1525b3f466
@ -18,6 +18,9 @@ impl SlabKind {
|
||||
} else if size < size_of::<FilePointer>() as u32 {
|
||||
Self::RelativeFreeList
|
||||
} else if (size as u64) <= PAGE_SIZE {
|
||||
// TODO
|
||||
// slabs of really big object are very inefficient.
|
||||
// find a better way/ allocate more pages at once e.g. at least 10 elements?
|
||||
Self::AbsoluteFreeList
|
||||
} else {
|
||||
panic!("invalid size")
|
||||
@ -469,6 +472,10 @@ impl SlabPointer {
|
||||
unsafe { db.modify(self.0) }
|
||||
}
|
||||
|
||||
pub fn size(&self, db: &Db) -> u32 {
|
||||
self.read(db).size.get()
|
||||
}
|
||||
|
||||
pub fn alloc(&self, db: &mut Db) -> FileRange {
|
||||
let Slab { mut head, size } = self.read(db);
|
||||
|
||||
|
34
src/lib.rs
34
src/lib.rs
@ -1,5 +1,10 @@
|
||||
use std::{
|
||||
borrow::BorrowMut, collections::HashMap, fmt::Debug, fs::File, mem::size_of, ops::Range,
|
||||
borrow::BorrowMut,
|
||||
collections::{BTreeMap, HashMap},
|
||||
fmt::Debug,
|
||||
fs::File,
|
||||
mem::size_of,
|
||||
ops::Range,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
@ -153,6 +158,7 @@ pub struct Reader {
|
||||
pub struct Db {
|
||||
file: File,
|
||||
map: MmapMut,
|
||||
slabs: BTreeMap<u32, SlabPointer>,
|
||||
state: Arc<AtomicArc<Snapshot>>,
|
||||
}
|
||||
|
||||
@ -241,9 +247,18 @@ impl Db {
|
||||
unsafe { self.modify_range_unchecked(Self::header_ptr().range(size_of::<Header>() as u64)) }
|
||||
}
|
||||
|
||||
pub fn add_slab(&mut self, size: u32) -> SlabPointer {
|
||||
fn add_slab(&mut self, size: u32) -> SlabPointer {
|
||||
let allocator_state = self.header().allocator_state;
|
||||
allocator_state.slabs.add_slab(self, size)
|
||||
let slab = allocator_state.slabs.add_slab(self, size);
|
||||
assert!(self.slabs.insert(size, slab).is_none());
|
||||
slab
|
||||
}
|
||||
|
||||
pub fn ensure_slab(&mut self, size: u32) -> SlabPointer {
|
||||
self.slabs
|
||||
.get(&size)
|
||||
.copied()
|
||||
.unwrap_or_else(|| self.add_slab(size))
|
||||
}
|
||||
|
||||
fn transaction(f: impl FnOnce(TransactionHandle)) {
|
||||
@ -392,8 +407,20 @@ impl Db {
|
||||
}))),
|
||||
file,
|
||||
map,
|
||||
slabs: BTreeMap::new(),
|
||||
};
|
||||
|
||||
let allocator_state = db.header().allocator_state;
|
||||
|
||||
let mut slabs = BTreeMap::new();
|
||||
|
||||
for slab in allocator_state.slabs.iter(&db) {
|
||||
let size = slab.size(&db);
|
||||
slabs.insert(size, slab);
|
||||
}
|
||||
|
||||
db.slabs = slabs;
|
||||
|
||||
unsafe {
|
||||
if len == 0 {
|
||||
*db.header_mut() = Header::default();
|
||||
@ -616,6 +643,7 @@ mod tests {
|
||||
|
||||
// alloc_and_free_many::<1>(&mut db, 3 * PAGE_SIZE);
|
||||
alloc_and_free_many::<4>(&mut db, PAGE_SIZE / 4 * 3);
|
||||
alloc_and_free_many::<4>(&mut db, PAGE_SIZE / 4 * 3);
|
||||
alloc_and_free_many::<16>(&mut db, PAGE_SIZE / 16 * 3);
|
||||
|
||||
let mut child = std::process::Command::new("hexdump")
|
||||
|
Loading…
Reference in New Issue
Block a user