mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-12 20:28:36 -07:00
vecs: part 3
This commit is contained in:
@@ -5,7 +5,7 @@ use std::{collections::HashMap, fs, io::BufReader, path::Path};
|
|||||||
|
|
||||||
use bincode::decode_from_std_read;
|
use bincode::decode_from_std_read;
|
||||||
use bincode::{Decode, Encode, config};
|
use bincode::{Decode, Encode, config};
|
||||||
use brk_core::{Error, Result};
|
use brk_core::Result;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
use crate::PAGE_SIZE;
|
use crate::PAGE_SIZE;
|
||||||
@@ -155,10 +155,8 @@ impl Layout {
|
|||||||
Some(region)
|
Some(region)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_hole_and_is_big_enough(&self, start: u64, gap_needed: u64) -> bool {
|
pub fn get_hole(&self, start: u64) -> Option<u64> {
|
||||||
self.start_to_hole
|
self.start_to_hole.get(&start).copied()
|
||||||
.get(&start)
|
|
||||||
.is_some_and(|gap| *gap >= gap_needed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_or_compress_hole_to_right(&mut self, start: u64, compress_by: u64) {
|
pub fn remove_or_compress_hole_to_right(&mut self, start: u64, compress_by: u64) {
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ use parking_lot::{RwLock, RwLockReadGuard};
|
|||||||
mod layout;
|
mod layout;
|
||||||
mod reader;
|
mod reader;
|
||||||
mod region;
|
mod region;
|
||||||
|
mod regions;
|
||||||
|
|
||||||
use layout::*;
|
use layout::*;
|
||||||
|
use reader::*;
|
||||||
use region::*;
|
use region::*;
|
||||||
|
use regions::*;
|
||||||
use crate::file::reader::Reader;
|
|
||||||
|
|
||||||
pub const PAGE_SIZE: u64 = 4096;
|
pub const PAGE_SIZE: u64 = 4096;
|
||||||
|
|
||||||
@@ -109,46 +110,53 @@ impl File {
|
|||||||
let reserved = region_lock.reserved();
|
let reserved = region_lock.reserved();
|
||||||
let left = region_lock.left();
|
let left = region_lock.left();
|
||||||
let data_len = data.len() as u64;
|
let data_len = data.len() as u64;
|
||||||
|
drop(region_lock);
|
||||||
|
|
||||||
let new_left = at.map_or_else(|| left, |at| reserved - (at - start));
|
let new_left = at.map_or_else(|| left, |at| reserved - (at - start));
|
||||||
let new_len = reserved - new_left;
|
let new_len = reserved - new_left;
|
||||||
|
|
||||||
|
// Write to reserved space if possible
|
||||||
if new_left >= data_len {
|
if new_left >= data_len {
|
||||||
drop(region_lock);
|
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
||||||
|
|
||||||
let mut region_lock = region.write();
|
let mut region_lock = region.write();
|
||||||
region_lock.set_len(new_len);
|
region_lock.set_len(new_len);
|
||||||
|
|
||||||
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
// TODO: Flush layout
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let layout_lock = self.layout.read();
|
let mut layout_lock = self.layout.write();
|
||||||
|
|
||||||
let hole_start = start + reserved;
|
let hole_start = start + reserved;
|
||||||
if layout_lock.has_hole_and_is_big_enough(hole_start, reserved) {
|
let hole = layout_lock.get_hole(hole_start);
|
||||||
drop(layout_lock);
|
|
||||||
let mut layout_lock = self.layout.write();
|
// Expand region to the right if possible
|
||||||
|
if hole.is_some_and(|gap| gap >= reserved) {
|
||||||
|
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
||||||
|
|
||||||
layout_lock.remove_or_compress_hole_to_right(hole_start, reserved);
|
layout_lock.remove_or_compress_hole_to_right(hole_start, reserved);
|
||||||
drop(layout_lock);
|
drop(layout_lock);
|
||||||
|
|
||||||
drop(region_lock);
|
|
||||||
let mut region_lock = region.write();
|
let mut region_lock = region.write();
|
||||||
region_lock.set_len(new_len);
|
region_lock.set_len(new_len);
|
||||||
region_lock.set_reserved(reserved * 2);
|
region_lock.set_reserved(reserved * 2);
|
||||||
|
|
||||||
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
// TODO: Flush layout
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let reserved = reserved * 2;
|
let reserved = reserved * 2;
|
||||||
|
|
||||||
|
// Find hole big enough to move the region or the next depending on which is smaller to if possible
|
||||||
if let Some(hole_start) = layout_lock.find_smallest_adequate_hole(reserved) {
|
if let Some(hole_start) = layout_lock.find_smallest_adequate_hole(reserved) {
|
||||||
drop(layout_lock);
|
|
||||||
let mut layout_lock = self.layout.write();
|
|
||||||
layout_lock.remove_or_compress_hole_to_right(hole_start, reserved);
|
layout_lock.remove_or_compress_hole_to_right(hole_start, reserved);
|
||||||
|
// TODO: Before every drop of layout.write flush to disk
|
||||||
drop(layout_lock);
|
drop(layout_lock);
|
||||||
|
|
||||||
drop(region_lock);
|
// write
|
||||||
|
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
||||||
|
|
||||||
let mut region_lock = region.write();
|
let mut region_lock = region.write();
|
||||||
region_lock.set_start(hole_start);
|
region_lock.set_start(hole_start);
|
||||||
region_lock.set_len(new_len);
|
region_lock.set_len(new_len);
|
||||||
@@ -157,6 +165,9 @@ impl File {
|
|||||||
// TODO: create hole in prev position
|
// TODO: create hole in prev position
|
||||||
|
|
||||||
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
Self::write_to_mmap(&self.mmap.read(), at.unwrap_or(start), data);
|
||||||
|
|
||||||
|
// TODO: Flush layout
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy region to new position then lock and update region meta then remove
|
// copy region to new position then lock and update region meta then remove
|
||||||
|
|||||||
14
crates/brk_vecs/src/file/regions.rs
Normal file
14
crates/brk_vecs/src/file/regions.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::file::region::Region;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Regions {
|
||||||
|
file: fs::File,
|
||||||
|
id_to_index: HashMap<String, usize>,
|
||||||
|
index_to_region: Vec<Option<Arc<RwLock<Region>>>>,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user