Allow allocating in different sizes

This commit is contained in:
Jeremy Soller
2024-02-14 12:53:06 -07:00
parent ab0bb9aec7
commit 07e8093ee0
3 changed files with 10 additions and 10 deletions
+6 -6
View File
@@ -26,10 +26,10 @@ impl Allocator {
free
}
pub fn allocate(&mut self) -> Option<u64> {
pub fn allocate(&mut self, addr_level: usize) -> Option<u64> {
// First, find the lowest level with a free block
let mut addr_opt = None;
let mut level = 0;
let mut level = addr_level;
while level < self.levels.len() {
if !self.levels[level].is_empty() {
addr_opt = self.levels[level].pop();
@@ -38,9 +38,9 @@ impl Allocator {
level += 1;
}
// Next, if a free block was found, split it up until you have a usable level 0 block
// Next, if a free block was found, split it up until you have a usable block of the right level
let addr = addr_opt?;
while level > 0 {
while level > addr_level {
level -= 1;
let level_size = 1 << level;
self.levels[level].push(addr + level_size);
@@ -79,10 +79,10 @@ impl Allocator {
addr_opt
}
pub fn deallocate(&mut self, mut addr: u64) {
pub fn deallocate(&mut self, mut addr: u64, addr_level: usize) {
// See if block matches with a sibling - if so, join them into a larger block, and populate
// this all the way to the top level
let mut level = 0;
let mut level = addr_level;
loop {
while level >= self.levels.len() {
self.levels.push(Vec::new());
+1 -1
View File
@@ -253,7 +253,7 @@ impl<D: Disk> FileSystem<D> {
}
} else {
for i in 0..count {
self.allocator.deallocate(addr + i as u64);
self.allocator.deallocate(addr + i as u64, 0);
}
}
}
+3 -3
View File
@@ -53,7 +53,7 @@ impl<'a, D: Disk> Transaction<'a, D> {
// Unsafe because order must be done carefully and changes must be flushed to disk
unsafe fn allocate(&mut self) -> Result<u64> {
match self.allocator.allocate() {
match self.allocator.allocate(0) {
Some(addr) => {
self.allocator_log.push_back(AllocEntry::new(addr, -1));
Ok(addr)
@@ -83,7 +83,7 @@ impl<'a, D: Disk> Transaction<'a, D> {
if found {
// Deallocate immediately since it is an allocation that was not needed
self.allocator.deallocate(addr);
self.allocator.deallocate(addr, 0);
} else {
// Deallocate later when syncing filesystem, to avoid re-use
self.deallocate.push(addr);
@@ -164,7 +164,7 @@ impl<'a, D: Disk> Transaction<'a, D> {
// De-allocate old blocks (after allocation to prevent re-use)
//TODO: optimize allocator log in memory
while let Some(addr) = self.deallocate.pop() {
self.allocator.deallocate(addr);
self.allocator.deallocate(addr, 0);
self.allocator_log.push_back(AllocEntry::new(addr, 1));
}