added the builder
This commit is contained in:
parent
686a7b9ebb
commit
a50934393e
6 changed files with 104 additions and 27 deletions
44
src/builder.rs
Normal file
44
src/builder.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use std::mem;
|
||||
use crate::page::{self, Page};
|
||||
use crate::record::Record;
|
||||
|
||||
struct Builder {
|
||||
current_page: Page,
|
||||
n_records_on_current_page: u16,
|
||||
leaf_pages: Vec<Page>,
|
||||
}
|
||||
|
||||
|
||||
impl Builder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
current_page: Page::new_leaf(),
|
||||
n_records_on_current_page: 0,
|
||||
leaf_pages: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_record(&mut self, record: Record) {
|
||||
if self.current_page_is_full(&record) {
|
||||
self.finish_current_page();
|
||||
self.leaf_pages.push(mem::replace(&mut self.current_page, Page::new_leaf()));
|
||||
self.n_records_on_current_page = 0;
|
||||
}
|
||||
|
||||
self.current_page.key = record.rowid; //clone?
|
||||
self.current_page.put_vec_u8_bw(record.to_bytes());
|
||||
self.current_page.put_u16(self.current_page.get_bw_position() as u16);
|
||||
self.n_records_on_current_page += 1;
|
||||
}
|
||||
|
||||
fn current_page_is_full(&self, record: &Record) -> bool {
|
||||
self.current_page.get_bw_position() - record.get_length() <= self.current_page.get_fw_position() + 5
|
||||
}
|
||||
|
||||
fn finish_current_page(&mut self) {
|
||||
self.current_page.set_fw_position(page::POSITION_CELL_COUNT);
|
||||
self.current_page.put_u16(self.n_records_on_current_page);
|
||||
self.current_page.put_u16(self.current_page.get_bw_position());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6,14 +6,14 @@ use byteorder::{BigEndian, ByteOrder};
|
|||
/// - big endian only
|
||||
pub struct ByteBuffer {
|
||||
pub data: Vec<u8>,
|
||||
pub fw_position: usize,
|
||||
pub bw_position: usize,
|
||||
pub fw_position: u16,
|
||||
pub bw_position: u16,
|
||||
}
|
||||
|
||||
impl ByteBuffer {
|
||||
pub fn new(size: usize) -> Self {
|
||||
pub fn new(size: u16) -> Self {
|
||||
Self {
|
||||
data: vec![0; size],
|
||||
data: vec![0; size as usize],
|
||||
fw_position: 0,
|
||||
bw_position: size,
|
||||
}
|
||||
|
|
@ -22,23 +22,31 @@ impl ByteBuffer {
|
|||
/// forward put unsigned byte array
|
||||
pub fn put_u8a(&mut self, bytes: &[u8]) {
|
||||
for v in bytes {
|
||||
self.data[self.fw_position] = *v;
|
||||
self.data[self.fw_position as usize] = *v;
|
||||
self.fw_position += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put_u8v(&mut self, bytes: &Vec<u8>) {
|
||||
for v in bytes {
|
||||
self.data[self.fw_position] = *v;
|
||||
self.data[self.fw_position as usize] = *v;
|
||||
self.fw_position += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// backward put unsigned byte array
|
||||
pub fn put_u8a_bw(&mut self, bytes: &[u8]) {
|
||||
self.bw_position -= bytes.len();
|
||||
self.bw_position -= bytes.len() as u16;
|
||||
for v in bytes {
|
||||
self.data[self.bw_position] = *v;
|
||||
self.data[self.bw_position as usize] = *v;
|
||||
self.bw_position += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put_vec_u8_bw(&mut self, bytes: Vec<u8>) {
|
||||
self.bw_position -= bytes.len() as u16;
|
||||
for v in bytes {
|
||||
self.data[self.bw_position as usize] = v;
|
||||
self.bw_position += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ mod bytebuffer;
|
|||
mod values;
|
||||
mod varint;
|
||||
mod record;
|
||||
|
||||
mod builder;
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
36
src/page.rs
36
src/page.rs
|
|
@ -1,6 +1,7 @@
|
|||
use crate::bytebuffer::ByteBuffer;
|
||||
use crate::database;
|
||||
const POSITION_CELL_COUNT: u32 = 3;
|
||||
|
||||
pub const POSITION_CELL_COUNT: u16 = 3;
|
||||
const START_OF_CONTENT_AREA: u32 = 5;
|
||||
|
||||
pub enum PageType {
|
||||
|
|
@ -11,16 +12,16 @@ pub enum PageType {
|
|||
/// Represents an SQLite page
|
||||
pub struct Page {
|
||||
data: ByteBuffer,
|
||||
key: i64,
|
||||
pub key: u64,
|
||||
children: Vec<Page>,
|
||||
number: u32,
|
||||
page_type: PageType,
|
||||
}
|
||||
|
||||
impl Page {
|
||||
fn with_capacity(size: u16, page_type: PageType) -> Self {
|
||||
pub fn with_capacity(size: u16, page_type: PageType) -> Self {
|
||||
Self {
|
||||
data: ByteBuffer::new(size as usize),
|
||||
data: ByteBuffer::new(size as u16),
|
||||
key: 0,
|
||||
children: Vec::new(),
|
||||
number: 0,
|
||||
|
|
@ -28,13 +29,13 @@ impl Page {
|
|||
}
|
||||
}
|
||||
|
||||
fn new_leaf() -> Self {
|
||||
pub fn new_leaf() -> Self {
|
||||
let mut page = Page::with_capacity(database::DEFAULT_PAGE_SIZE, PageType::Leaf);
|
||||
page.put_u8(database::TABLE_LEAF_PAGE);
|
||||
page
|
||||
}
|
||||
|
||||
fn new_interior() -> Self {
|
||||
pub fn new_interior() -> Self {
|
||||
let mut page = Page::with_capacity(database::DEFAULT_PAGE_SIZE, PageType::Interior);
|
||||
page.put_u8(database::TABLE_LEAF_PAGE);
|
||||
page
|
||||
|
|
@ -44,22 +45,41 @@ impl Page {
|
|||
self.children.push(child);
|
||||
}
|
||||
|
||||
pub fn fw_position(&mut self, new_position: usize) {
|
||||
pub fn set_fw_position(&mut self, new_position: u16) {
|
||||
self.data.fw_position = new_position;
|
||||
}
|
||||
|
||||
pub fn bw_position(&mut self, new_position: usize) {
|
||||
pub fn get_fw_position(&self) -> u16 {
|
||||
self.data.fw_position
|
||||
}
|
||||
pub fn set_bw_position(&mut self, new_position: u16) {
|
||||
self.data.bw_position = new_position;
|
||||
}
|
||||
|
||||
pub fn get_bw_position(&self) -> u16 {
|
||||
self.data.bw_position
|
||||
}
|
||||
|
||||
pub fn put_u8a(&mut self, value: &[u8]) {
|
||||
self.data.put_u8a(value);
|
||||
}
|
||||
|
||||
pub fn put_u8a_bw(&mut self, value: &[u8]) {
|
||||
self.data.put_u8a_bw(value);
|
||||
}
|
||||
|
||||
pub fn put_vec_u8_bw(&mut self, value: Vec<u8>) {
|
||||
self.data.put_vec_u8_bw(value);
|
||||
}
|
||||
|
||||
pub fn put_u8(&mut self, value: u8) {
|
||||
self.data.put_u8(value);
|
||||
}
|
||||
|
||||
pub fn put_u8_bw(&mut self, value: u8) {
|
||||
self.data.put_u8_bw(value);
|
||||
}
|
||||
|
||||
pub fn put_u16(&mut self, value: u16) {
|
||||
self.data.put_u16(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use crate::bytebuffer::ByteBuffer;
|
|||
use crate::values::*;
|
||||
use crate::varint;
|
||||
|
||||
struct Record {
|
||||
rowid: u64,
|
||||
pub struct Record {
|
||||
pub rowid: u64,
|
||||
//or should it be i64??
|
||||
values: Vec<Value>,
|
||||
}
|
||||
|
|
@ -20,14 +20,12 @@ impl Record {
|
|||
self.values.push(value);
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> Vec<u8> {
|
||||
let record_length: usize = self.values.iter()
|
||||
.map(|v| v.get_length())
|
||||
.sum();
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let record_length = self.get_length();
|
||||
let length_bytes = varint::write(record_length as u64);
|
||||
let rowid_bytes = varint::write(self.rowid);
|
||||
|
||||
let mut buffer = ByteBuffer::new(length_bytes.len() + rowid_bytes.len() + record_length);
|
||||
let mut buffer = ByteBuffer::new(length_bytes.len() as u16 + rowid_bytes.len() as u16 + record_length);
|
||||
buffer.put_u8v(&length_bytes);
|
||||
buffer.put_u8v(&rowid_bytes);
|
||||
|
||||
|
|
@ -48,6 +46,13 @@ impl Record {
|
|||
}
|
||||
buffer.data
|
||||
}
|
||||
|
||||
pub fn get_length(&self) -> u16 {
|
||||
let record_length: u16 = self.values.iter()
|
||||
.map(|v| v.get_length())
|
||||
.sum();
|
||||
record_length
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ pub struct Value {
|
|||
|
||||
|
||||
impl Value {
|
||||
pub fn get_length(&self) -> usize {
|
||||
self.datatype.len() + self.data.len()
|
||||
pub fn get_length(&self) -> u16 {
|
||||
(self.datatype.len() + self.data.len()) as u16
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue