use super::{state::ChunkCount, TestDB};
use crate::{BlockKey, size::ByteSize, tests::util::size_bytes};
impl TestDB {
pub async fn write(
&mut self,
bytes: &[u8],
creates_data_file: bool,
) -> Result<BlockKey, String> {
let block_key = self
.block_db
.write(bytes)
.await
.map_err(|err| format!("Failed to write bytes \n {err:?}"))?;
let bytes_size = size_bytes(bytes, self.chunk_size);
let data_file_id = &block_key.data_file_id;
if creates_data_file {
self.test_state.data_file_count += 1;
}
let ByteSize {
used_bytes: block_db_used_bytes,
free_bytes: block_db_free_bytes,
} = &mut self.test_state.block_db_byte_size;
let ByteSize {
used_bytes: data_file_used_bytes,
free_bytes: data_file_free_bytes,
} = self
.test_state
.data_file_byte_size_map
.entry(data_file_id.to_string())
.or_default();
let ChunkCount { used, free } = self
.test_state
.data_file_chunk_count_map
.entry(data_file_id.to_string())
.or_default();
let introduced_chunks = bytes_size / self.chunk_size;
let previous_free_chunks = *free;
let new_free_chunks =
(previous_free_chunks as i64 - introduced_chunks as i64).max(0) as usize;
let used_free_chunks = previous_free_chunks - new_free_chunks;
let used_free_bytes = used_free_chunks * self.chunk_size;
let new_introduced_chunks = introduced_chunks - used_free_chunks;
let new_introduced_bytes = new_introduced_chunks * self.chunk_size;
*free = new_free_chunks;
*used += new_introduced_chunks + used_free_chunks;
*block_db_used_bytes += new_introduced_bytes + used_free_bytes;
*block_db_free_bytes -= used_free_bytes;
*data_file_used_bytes += new_introduced_bytes + used_free_bytes;
*data_file_free_bytes -= used_free_bytes;
self.test_state
.assert_against_block_db(&self.block_db)
.await?;
self.read(&block_key, Some(bytes)).await?;
Ok(block_key)
}
}