140 lines
5 KiB
Rust
140 lines
5 KiB
Rust
use crate::binary_coding::{decode, decode_sequence, encode, encode_sequence};
|
|
use crate::error::{DecodeErrorKind, Error};
|
|
use crate::store::{Column, Result};
|
|
use std::mem::size_of;
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct StoreHeader {
|
|
pub table_folder: PathBuf, // This one is not encoded into the file
|
|
|
|
pub number_of_columns: usize,
|
|
pub deleted_count: usize,
|
|
pub total_count: usize,
|
|
pub primary_column: Column,
|
|
pub indexed_columns: Vec<bool>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct StoreHeaderFixedPart {
|
|
pub table_folder: PathBuf, // This one is not encoded into the file
|
|
|
|
pub number_of_columns: usize,
|
|
pub deleted_count: usize,
|
|
pub total_count: usize,
|
|
pub primary_column: Column,
|
|
}
|
|
|
|
impl StoreHeader {
|
|
pub const NUMBER_OF_COLUMNS_SIZE: usize = size_of::<usize>();
|
|
pub const DELETED_COUNT_SIZE: usize = size_of::<usize>();
|
|
pub const TOTAL_COUNT_SIZE: usize = size_of::<usize>();
|
|
pub const PRIMARY_COLUMN_SIZE: usize = size_of::<Column>();
|
|
pub const FIXED_SIZE: usize = Self::NUMBER_OF_COLUMNS_SIZE
|
|
+ Self::DELETED_COUNT_SIZE
|
|
+ Self::TOTAL_COUNT_SIZE
|
|
+ Self::PRIMARY_COLUMN_SIZE;
|
|
|
|
pub const NUMBER_OF_COLUMNS_OFFSET: usize = 0;
|
|
pub const DELETED_COUNT_OFFSET: usize =
|
|
Self::NUMBER_OF_COLUMNS_OFFSET + Self::NUMBER_OF_COLUMNS_SIZE;
|
|
pub const TOTAL_COUNT_OFFSET: usize = Self::DELETED_COUNT_OFFSET + Self::DELETED_COUNT_SIZE;
|
|
pub const PRIMARY_COLUMN_OFFSET: usize = Self::TOTAL_COUNT_OFFSET + Self::TOTAL_COUNT_SIZE;
|
|
#[allow(dead_code)]
|
|
pub const INDEXED_COLUMNS_OFFSET: usize =
|
|
Self::PRIMARY_COLUMN_OFFSET + Self::PRIMARY_COLUMN_SIZE;
|
|
|
|
fn indexed_columns_size(number_of_columns: usize) -> usize {
|
|
size_of::<bool>() * number_of_columns
|
|
}
|
|
|
|
pub fn size(number_of_columns: usize) -> usize {
|
|
Self::FIXED_SIZE + Self::indexed_columns_size(number_of_columns)
|
|
}
|
|
|
|
pub fn encode(&self) -> Result<Vec<u8>> {
|
|
let mut result = encode(&self.number_of_columns)?;
|
|
result.append(&mut encode(&self.deleted_count)?);
|
|
result.append(&mut encode(&self.total_count)?);
|
|
result.append(&mut encode(&self.primary_column)?);
|
|
result.append(&mut encode_sequence(&self.indexed_columns)?);
|
|
Ok(result)
|
|
}
|
|
|
|
pub fn buffer_for_fixed_decoding() -> [u8; Self::FIXED_SIZE] {
|
|
[0; Self::FIXED_SIZE]
|
|
}
|
|
|
|
pub fn buffer_for_rest_decoding(header: &StoreHeaderFixedPart) -> Vec<u8> {
|
|
vec![0; Self::indexed_columns_size(header.number_of_columns)]
|
|
}
|
|
|
|
pub async fn decode_fixed(
|
|
table_folder: &PathBuf,
|
|
result: &[u8],
|
|
) -> Result<StoreHeaderFixedPart> {
|
|
let (number_of_columns, _) = decode::<usize>(
|
|
&result[Self::NUMBER_OF_COLUMNS_OFFSET
|
|
..Self::NUMBER_OF_COLUMNS_OFFSET + Self::NUMBER_OF_COLUMNS_SIZE],
|
|
)
|
|
.map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderNumberOfColumns, e))?;
|
|
let (deleted_count, _) = decode::<usize>(
|
|
&result
|
|
[Self::DELETED_COUNT_OFFSET..Self::DELETED_COUNT_OFFSET + Self::DELETED_COUNT_SIZE],
|
|
)
|
|
.map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderDeletedCount, e))?;
|
|
let (total_count, _) = decode::<usize>(
|
|
&result[Self::TOTAL_COUNT_OFFSET..Self::TOTAL_COUNT_OFFSET + Self::TOTAL_COUNT_SIZE],
|
|
)
|
|
.map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderTotalCount, e))?;
|
|
let (primary_column, _) = decode::<Column>(
|
|
&result[Self::PRIMARY_COLUMN_OFFSET
|
|
..Self::PRIMARY_COLUMN_OFFSET + Self::PRIMARY_COLUMN_SIZE],
|
|
)
|
|
.map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderPrimaryColumn, e))?;
|
|
let header = StoreHeaderFixedPart {
|
|
table_folder: table_folder.clone(),
|
|
number_of_columns,
|
|
deleted_count,
|
|
total_count,
|
|
primary_column,
|
|
};
|
|
|
|
Ok(header)
|
|
}
|
|
|
|
pub async fn decode_rest(header: StoreHeaderFixedPart, result: &[u8]) -> Result<StoreHeader> {
|
|
let indexed_columns: Vec<bool> = decode_sequence::<bool>(header.number_of_columns, result)
|
|
.map_err(|e| Error::DecodeError(DecodeErrorKind::StoreHeaderIndexedColumns, e))?;
|
|
|
|
Ok(StoreHeader {
|
|
table_folder: header.table_folder,
|
|
number_of_columns: header.number_of_columns,
|
|
deleted_count: header.deleted_count,
|
|
total_count: header.total_count,
|
|
primary_column: header.primary_column,
|
|
|
|
indexed_columns,
|
|
})
|
|
}
|
|
|
|
// returns new count
|
|
pub fn increment_total_count(&mut self) -> usize {
|
|
self.total_count += 1;
|
|
self.total_count
|
|
}
|
|
|
|
// returns new count
|
|
pub fn increment_deleted_count(&mut self) -> usize {
|
|
self.deleted_count += 1;
|
|
self.deleted_count
|
|
}
|
|
|
|
pub fn is_column_indexed(&self, column: Column) -> bool {
|
|
self.indexed_columns[column as usize]
|
|
}
|
|
|
|
pub fn make_column_indexed(&mut self, column: Column) {
|
|
self.indexed_columns[column as usize] = true
|
|
}
|
|
}
|