Implement remove for blockfile.
This commit is contained in:
parent
48a62fc165
commit
2bb32e75b7
@ -6,17 +6,30 @@ async fn main()
|
||||
{
|
||||
std::fs::create_dir_all("data").ok();
|
||||
|
||||
println!("BLOCKFILE");
|
||||
//println!("BLOCKFILE");
|
||||
|
||||
if let Ok(mut bf) = BlockFile::<16>::open("data/cache_data.bin").await {
|
||||
if let Ok(id) = bf.insert("This is a test of the block file system.".as_bytes()).await {
|
||||
let op = 0;
|
||||
|
||||
if let Ok(mut bf) = BlockFile::<32>::open("data/cache_data.bin").await {
|
||||
match op {
|
||||
0 => {
|
||||
for i in 0..1 {
|
||||
if let Ok(id) = bf.insert(format!("{} This is a test of the block file system {}.", i, i).as_bytes()).await {
|
||||
let data = String::from_utf8(bf.get(id).await.unwrap()).unwrap();
|
||||
println!("id {} = '{}'", id, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
1 => {
|
||||
bf.remove(12).await.ok();
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
} else {
|
||||
println!("Failed to open.");
|
||||
}
|
||||
|
||||
/*
|
||||
println!("TRIEFILE");
|
||||
|
||||
if let Ok(mut tf) = TrieFile::<8>::open("data/cache_index.bin").await {
|
||||
@ -62,4 +75,5 @@ async fn main()
|
||||
} else {
|
||||
println!("Failed to open index.");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
** [Header:16]
|
||||
** {AllocTable Head: <Depth:1> <Block:4> } (initial 0, 0)
|
||||
** {ObjectTable Head: <Depth:1> <Block:4> } (initial 0, 1)
|
||||
** {NextObject <Id:4>}
|
||||
**
|
||||
** [Object Table]
|
||||
** { <Pointer:4> <Length:4> }*
|
||||
@ -106,10 +107,7 @@ impl<const Z:usize> BlockFile<Z> {
|
||||
|
||||
// Allocate storage blocks
|
||||
let block_count = Self::block_count_from_size(data.len());
|
||||
//println!("block_count {}", block_count);
|
||||
|
||||
let blocks = self.allocate(block_count.max(1)).await?;
|
||||
//println!("blocks {}", blocks.len());
|
||||
|
||||
// Get object id
|
||||
let id = self.acquire_object(blocks[0], data.len()).await?;
|
||||
@ -200,10 +198,28 @@ impl<const Z:usize> BlockFile<Z> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove(&mut self, _id:usize) -> Result<(), std::io::Error>
|
||||
pub async fn remove(&mut self, id:usize) -> Result<(), std::io::Error>
|
||||
// Remove the object with the specified identifier and release its allocation.
|
||||
//
|
||||
{
|
||||
let mut block_data = [0u8; Z];
|
||||
|
||||
let mut blocks = Vec::new();
|
||||
let (mut block_id, _) = self.get_object(id).await?;
|
||||
|
||||
while block_id != 0 {
|
||||
blocks.push(block_id);
|
||||
|
||||
self.read_block(block_id, &mut block_data).await?;
|
||||
block_id = u32::unpack(&block_data, &mut (Z - 4)).unwrap_or_default();
|
||||
}
|
||||
|
||||
// Remove object listing.
|
||||
self.free_object(id).await?;
|
||||
|
||||
// Free allocated blocks.
|
||||
self.release(&blocks).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -466,6 +482,7 @@ impl<const Z:usize> BlockFile<Z> {
|
||||
let mut b32 = [0u8; 4];
|
||||
|
||||
let mut block_data = [0u8; Z];
|
||||
let zero = [0u8; Z];
|
||||
|
||||
// Read allocation table root block and depth from file.
|
||||
self.file.seek(SeekFrom::Start(0)).await?;
|
||||
@ -499,6 +516,8 @@ impl<const Z:usize> BlockFile<Z> {
|
||||
|
||||
block_data[byte as usize] &= !(1 << bit);
|
||||
self.write_block(page, &block_data).await?;
|
||||
|
||||
self.write_block(block, &zero).await.ok();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -661,6 +680,80 @@ impl<const Z:usize> BlockFile<Z> {
|
||||
Ok(object_id)
|
||||
}
|
||||
|
||||
async fn free_object(&mut self, id:usize) -> Result<(),std::io::Error>
|
||||
{
|
||||
let mut block_data = [0u8; Z];
|
||||
|
||||
let mut b8 = [0u8; 1];
|
||||
let mut b32 = [0u8; 4];
|
||||
|
||||
// Read allocation table root block and depth from file.
|
||||
self.file.seek(SeekFrom::Start(5)).await?;
|
||||
self.file.read_exact(&mut b8).await?;
|
||||
let mut depth = b8[0] as u32;
|
||||
|
||||
self.file.read_exact(&mut b32).await?;
|
||||
let mut block_id = u32::unpack(&b32, &mut 0).unwrap_or_default();
|
||||
|
||||
self.file.read_exact(&mut b32).await?;
|
||||
let object_id = u32::unpack(&b32, &mut 0).unwrap_or_default() as usize;
|
||||
|
||||
let mut basis = 0;
|
||||
|
||||
// Search table for first vacant or unallocated child.
|
||||
while depth > 0 {
|
||||
/*
|
||||
** Select child tables containing object_id until depth is 0.
|
||||
*/
|
||||
|
||||
self.read_block(block_id, &mut block_data).await?;
|
||||
|
||||
let cell_index = (id - basis) / Self::table_offset(depth) as usize;
|
||||
|
||||
let cell_start = cell_index * 4;
|
||||
let cell_data = u32::unpack(&block_data, &mut cell_start.clone()).unwrap_or_default();
|
||||
|
||||
let child_id = if cell_data != 0 {
|
||||
u32::unpack(&block_data, &mut cell_start.clone()).unwrap_or_default()
|
||||
} else {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::NotFound, "object id not valid"));
|
||||
};
|
||||
|
||||
// Update frame of reference to child table.
|
||||
block_id = child_id;
|
||||
basis = Self::table_cell_offset(depth, cell_index as u32, basis as u32) as usize;
|
||||
depth -= 1;
|
||||
}
|
||||
|
||||
// Get object pointer and length from cell.
|
||||
self.read_block(block_id, &mut block_data).await?;
|
||||
|
||||
let cell_index = (id - basis) / Self::table_offset(depth) as usize;
|
||||
let cell_start = cell_index * 8;
|
||||
|
||||
// Set Id
|
||||
let pack_location = (object_id as u32).pack();
|
||||
block_data[cell_start] = pack_location[0];
|
||||
block_data[cell_start + 1] = pack_location[1];
|
||||
block_data[cell_start + 2] = pack_location[2];
|
||||
block_data[cell_start + 3] = pack_location[3];
|
||||
|
||||
// Set Length
|
||||
block_data[cell_start + 4] = 0;
|
||||
block_data[cell_start + 5] = 0;
|
||||
block_data[cell_start + 6] = 0;
|
||||
block_data[cell_start + 7] = 0;
|
||||
|
||||
self.write_block(block_id, &block_data).await?;
|
||||
|
||||
// Update header with new pointer.
|
||||
let pack_pointer = (id as u32).pack();
|
||||
self.file.seek(SeekFrom::Start(10)).await?;
|
||||
self.file.write(&pack_pointer).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_object(&self, id:usize) -> Result<(u32, usize), std::io::Error>
|
||||
// Find initial block and data size of an object.
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user