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 {
|
} else if size < size_of::<FilePointer>() as u32 {
|
||||||
Self::RelativeFreeList
|
Self::RelativeFreeList
|
||||||
} else if (size as u64) <= PAGE_SIZE {
|
} 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
|
Self::AbsoluteFreeList
|
||||||
} else {
|
} else {
|
||||||
panic!("invalid size")
|
panic!("invalid size")
|
||||||
@ -469,6 +472,10 @@ impl SlabPointer {
|
|||||||
unsafe { db.modify(self.0) }
|
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 {
|
pub fn alloc(&self, db: &mut Db) -> FileRange {
|
||||||
let Slab { mut head, size } = self.read(db);
|
let Slab { mut head, size } = self.read(db);
|
||||||
|
|
||||||
|
34
src/lib.rs
34
src/lib.rs
@ -1,5 +1,10 @@
|
|||||||
use std::{
|
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,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,6 +158,7 @@ pub struct Reader {
|
|||||||
pub struct Db {
|
pub struct Db {
|
||||||
file: File,
|
file: File,
|
||||||
map: MmapMut,
|
map: MmapMut,
|
||||||
|
slabs: BTreeMap<u32, SlabPointer>,
|
||||||
state: Arc<AtomicArc<Snapshot>>,
|
state: Arc<AtomicArc<Snapshot>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,9 +247,18 @@ impl Db {
|
|||||||
unsafe { self.modify_range_unchecked(Self::header_ptr().range(size_of::<Header>() as u64)) }
|
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;
|
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)) {
|
fn transaction(f: impl FnOnce(TransactionHandle)) {
|
||||||
@ -392,8 +407,20 @@ impl Db {
|
|||||||
}))),
|
}))),
|
||||||
file,
|
file,
|
||||||
map,
|
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 {
|
unsafe {
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
*db.header_mut() = Header::default();
|
*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::<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::<4>(&mut db, PAGE_SIZE / 4 * 3);
|
||||||
alloc_and_free_many::<16>(&mut db, PAGE_SIZE / 16 * 3);
|
alloc_and_free_many::<16>(&mut db, PAGE_SIZE / 16 * 3);
|
||||||
|
|
||||||
let mut child = std::process::Command::new("hexdump")
|
let mut child = std::process::Command::new("hexdump")
|
||||||
|
Loading…
Reference in New Issue
Block a user