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();
|
std::fs::create_dir_all("data").ok();
|
||||||
|
|
||||||
println!("BLOCKFILE");
|
//println!("BLOCKFILE");
|
||||||
|
|
||||||
if let Ok(mut bf) = BlockFile::<16>::open("data/cache_data.bin").await {
|
let op = 0;
|
||||||
if let Ok(id) = bf.insert("This is a test of the block file system.".as_bytes()).await {
|
|
||||||
|
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();
|
let data = String::from_utf8(bf.get(id).await.unwrap()).unwrap();
|
||||||
println!("id {} = '{}'", id, data);
|
println!("id {} = '{}'", id, data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
bf.remove(12).await.ok();
|
||||||
|
}
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("Failed to open.");
|
println!("Failed to open.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
println!("TRIEFILE");
|
println!("TRIEFILE");
|
||||||
|
|
||||||
if let Ok(mut tf) = TrieFile::<8>::open("data/cache_index.bin").await {
|
if let Ok(mut tf) = TrieFile::<8>::open("data/cache_index.bin").await {
|
||||||
@ -62,4 +75,5 @@ async fn main()
|
|||||||
} else {
|
} else {
|
||||||
println!("Failed to open index.");
|
println!("Failed to open index.");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
** [Header:16]
|
** [Header:16]
|
||||||
** {AllocTable Head: <Depth:1> <Block:4> } (initial 0, 0)
|
** {AllocTable Head: <Depth:1> <Block:4> } (initial 0, 0)
|
||||||
** {ObjectTable Head: <Depth:1> <Block:4> } (initial 0, 1)
|
** {ObjectTable Head: <Depth:1> <Block:4> } (initial 0, 1)
|
||||||
|
** {NextObject <Id:4>}
|
||||||
**
|
**
|
||||||
** [Object Table]
|
** [Object Table]
|
||||||
** { <Pointer:4> <Length:4> }*
|
** { <Pointer:4> <Length:4> }*
|
||||||
@ -106,10 +107,7 @@ impl<const Z:usize> BlockFile<Z> {
|
|||||||
|
|
||||||
// Allocate storage blocks
|
// Allocate storage blocks
|
||||||
let block_count = Self::block_count_from_size(data.len());
|
let block_count = Self::block_count_from_size(data.len());
|
||||||
//println!("block_count {}", block_count);
|
|
||||||
|
|
||||||
let blocks = self.allocate(block_count.max(1)).await?;
|
let blocks = self.allocate(block_count.max(1)).await?;
|
||||||
//println!("blocks {}", blocks.len());
|
|
||||||
|
|
||||||
// Get object id
|
// Get object id
|
||||||
let id = self.acquire_object(blocks[0], data.len()).await?;
|
let id = self.acquire_object(blocks[0], data.len()).await?;
|
||||||
@ -200,10 +198,28 @@ impl<const Z:usize> BlockFile<Z> {
|
|||||||
Ok(())
|
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.
|
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +482,7 @@ impl<const Z:usize> BlockFile<Z> {
|
|||||||
let mut b32 = [0u8; 4];
|
let mut b32 = [0u8; 4];
|
||||||
|
|
||||||
let mut block_data = [0u8; Z];
|
let mut block_data = [0u8; Z];
|
||||||
|
let zero = [0u8; Z];
|
||||||
|
|
||||||
// Read allocation table root block and depth from file.
|
// Read allocation table root block and depth from file.
|
||||||
self.file.seek(SeekFrom::Start(0)).await?;
|
self.file.seek(SeekFrom::Start(0)).await?;
|
||||||
@ -499,6 +516,8 @@ impl<const Z:usize> BlockFile<Z> {
|
|||||||
|
|
||||||
block_data[byte as usize] &= !(1 << bit);
|
block_data[byte as usize] &= !(1 << bit);
|
||||||
self.write_block(page, &block_data).await?;
|
self.write_block(page, &block_data).await?;
|
||||||
|
|
||||||
|
self.write_block(block, &zero).await.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -661,6 +680,80 @@ impl<const Z:usize> BlockFile<Z> {
|
|||||||
Ok(object_id)
|
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>
|
async fn get_object(&self, id:usize) -> Result<(u32, usize), std::io::Error>
|
||||||
// Find initial block and data size of an object.
|
// Find initial block and data size of an object.
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user