Skip to content
Snippets Groups Projects
Unverified Commit 07e8093e authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Allow allocating in different sizes

parent ab0bb9ae
No related branches found
No related tags found
No related merge requests found
......@@ -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());
......
......@@ -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);
}
}
}
......
......@@ -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));
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment