Remove redundant sort logic for add_range_back_to_free_manager
This commit is contained in:
parent
70dbf84782
commit
849e35f01e
@ -2,11 +2,12 @@
|
|||||||
// Currently only use simple vector as the base structure.
|
// Currently only use simple vector as the base structure.
|
||||||
//
|
//
|
||||||
// Basically use address-ordered first fit to find free ranges.
|
// Basically use address-ordered first fit to find free ranges.
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use super::vm_util::VMMapAddr;
|
use super::vm_util::VMMapAddr;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
static INITIAL_SIZE: usize = 100;
|
const INITIAL_SIZE: usize = 100;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct VMFreeSpaceManager {
|
pub struct VMFreeSpaceManager {
|
||||||
@ -129,21 +130,77 @@ impl VMFreeSpaceManager {
|
|||||||
|
|
||||||
pub fn add_range_back_to_free_manager(&mut self, dirty_range: &VMRange) -> Result<()> {
|
pub fn add_range_back_to_free_manager(&mut self, dirty_range: &VMRange) -> Result<()> {
|
||||||
let mut free_list = &mut self.free_manager;
|
let mut free_list = &mut self.free_manager;
|
||||||
free_list.push(*dirty_range);
|
|
||||||
// Sort and merge small ranges
|
// If the free list is empty, insert the dirty range and it's done.
|
||||||
free_list.sort_unstable_by(|range_a, range_b| range_a.start().cmp(&range_b.start()));
|
if free_list.is_empty() {
|
||||||
|
free_list.push(*dirty_range);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let dirty_range_start = dirty_range.start();
|
||||||
|
let dirty_range_end = dirty_range.end();
|
||||||
|
|
||||||
|
// If the dirty range is before the first free range or after the last free range
|
||||||
|
let head_range = &mut free_list[0];
|
||||||
|
match dirty_range_end.cmp(&head_range.start()) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
head_range.set_start(dirty_range_start);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Ordering::Less => {
|
||||||
|
free_list.insert(0, *dirty_range);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
let tail_range = free_list.last_mut().unwrap();
|
||||||
|
match dirty_range_start.cmp(&tail_range.end()) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
tail_range.set_end(dirty_range_end);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Ordering::Greater => {
|
||||||
|
free_list.push(*dirty_range);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
// The dirty range must be between some two ranges.
|
||||||
|
debug_assert!(free_list.len() >= 2);
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
while (idx < free_list.len() - 1) {
|
|
||||||
|
while idx < free_list.len() - 1 {
|
||||||
|
let left_range = free_list[idx];
|
||||||
let right_range = free_list[idx + 1];
|
let right_range = free_list[idx + 1];
|
||||||
let mut left_range = &mut free_list[idx];
|
|
||||||
if left_range.end() == right_range.start() {
|
if left_range.end() <= dirty_range_start && dirty_range_end <= right_range.start() {
|
||||||
left_range.set_end(right_range.end());
|
match (
|
||||||
free_list.remove(idx + 1);
|
dirty_range.is_contiguous_with(&left_range),
|
||||||
continue;
|
dirty_range.is_contiguous_with(&right_range),
|
||||||
|
) {
|
||||||
|
(true, true) => {
|
||||||
|
let left_range = &mut free_list[idx];
|
||||||
|
left_range.set_end(right_range.end());
|
||||||
|
free_list.remove(idx + 1);
|
||||||
|
}
|
||||||
|
(true, false) => {
|
||||||
|
let left_range = &mut free_list[idx];
|
||||||
|
left_range.set_end(dirty_range_end);
|
||||||
|
}
|
||||||
|
(false, true) => {
|
||||||
|
let right_range = &mut free_list[idx + 1];
|
||||||
|
right_range.set_start(dirty_range_start);
|
||||||
|
}
|
||||||
|
(false, false) => {
|
||||||
|
free_list.insert(idx + 1, *dirty_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
trace!("after add range back free list = {:?}", free_list);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,10 @@ impl VMRange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_contiguous_with(&self, other: &VMRange) -> bool {
|
||||||
|
self.start == other.end || self.end == other.start
|
||||||
|
}
|
||||||
|
|
||||||
pub unsafe fn as_slice(&self) -> &[u8] {
|
pub unsafe fn as_slice(&self) -> &[u8] {
|
||||||
let buf_ptr = self.start() as *const u8;
|
let buf_ptr = self.start() as *const u8;
|
||||||
let buf_size = self.size() as usize;
|
let buf_size = self.size() as usize;
|
||||||
|
Loading…
Reference in New Issue
Block a user