Refactor Store trait to use &String for input. Implement index node serialization.

This commit is contained in:
femsci 2023-02-03 12:29:38 +01:00
parent 02c01ffa2c
commit 179b220c2e
Signed by: femsci
GPG key ID: 08F7911F0E650C67
4 changed files with 120 additions and 27 deletions

View file

@ -24,5 +24,15 @@ fn main() {
Ok(x) => x,
};
store.get_creds("nya".to_string(), "meow".to_string());
let (key, specifier) = ("nya".to_string(), "meow".to_string());
match store.get_creds(&key, &specifier) {
Some(x) => {
println!("Credentials: {:?}", x);
}
None => println!(
"Credentials for key '{}' and specifier '{}' not found...",
key, specifier
),
}
}

View file

@ -4,8 +4,7 @@ use std::{
fs::File,
hash::{Hash, Hasher},
io::{BufReader, Read, Seek, SeekFrom, Write},
iter::TakeWhile,
path::{Iter, Path},
path::Path,
};
use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit, Nonce};
@ -230,7 +229,7 @@ fn try_create_store(path: &String, passphrase: &Vec<u8>) -> bool {
let meta = LocalStoreMeta {
record_count: 0,
specifier_count: 0,
index_node_arity: 64,
index_node_arity: 16,
data_block_size: 8092,
data_offset: 0,
};
@ -254,6 +253,13 @@ fn try_create_store(path: &String, passphrase: &Vec<u8>) -> bool {
header.chksum_crc = header.get_checksum();
let mut index_block: Vec<u8> = vec![0; meta.data_block_size as usize];
let root_node_buf = IndexNode {
node_type: IndexNodeType::Leaf,
children: Vec::new(),
}
.serialize(&meta);
index_block[0..root_node_buf.len()].copy_from_slice(&root_node_buf);
let mut buf = serialize_header(&header);
@ -500,20 +506,25 @@ impl LocalRecord {
}
impl Store for LocalStore {
fn get_creds(&self, specifier: String, key: String) -> Option<StoreRecord> {
self.btree_find_key(&key);
fn get_creds(&self, specifier: &String, key: &String) -> Option<StoreRecord> {
match self.btree_find_key(&key) {
Some(x) => {
println!("Found: {}", x);
todo!()
}
None => return None,
}
}
fn get_creds_by_specifier(&self, specifier: String) -> Vec<StoreRecord> {
fn get_creds_by_specifier(&self, specifier: &String) -> Vec<StoreRecord> {
todo!()
}
fn store_creds(
&self,
specifier: String,
key: String,
value: Vec<u8>,
specifier: &String,
key: &String,
value: &Vec<u8>,
r#type: RecordType,
meta: Option<String>,
) {
@ -521,11 +532,11 @@ impl Store for LocalStore {
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
enum IndexNodeType {
Internal,
Leaf,
Invalid,
Internal = 1,
Leaf = 2,
Invalid = 0,
}
impl From<u8> for IndexNodeType {
@ -557,6 +568,20 @@ impl IndexNode {
fn len(&self) -> usize {
self.children.len()
}
fn serialize(&self, meta: &LocalStoreMeta) -> Vec<u8> {
let mut buf: Vec<u8> = vec![0; 16 * meta.index_node_arity as usize + 2];
let mut cnt = 2;
for child in self.children() {
buf[cnt..(cnt + 8)].copy_from_slice(&child.key.to_be_bytes());
buf[(cnt + 8)..(cnt + 16)].copy_from_slice(&child.pointer.to_be_bytes());
cnt += 16;
}
buf[0] = self.node_type as u8;
buf
}
}
impl LocalStore {
@ -740,7 +765,7 @@ mod tests {
StoreRecord,
};
use super::LocalRecord;
use super::{IndexNode, IndexNodeEntry, IndexNodeType, LocalRecord};
#[test]
fn header_size_const_greater_than_realsize() {
@ -816,4 +841,62 @@ mod tests {
assert_eq!(serialized, reserialized);
}
#[test]
fn index_node_serialize() {
let root = IndexNode {
node_type: IndexNodeType::Internal,
children: vec![IndexNodeEntry {
key: 1,
pointer: 258,
}],
};
let leaf = IndexNode {
node_type: IndexNodeType::Leaf,
children: vec![
IndexNodeEntry {
key: 1,
pointer: 516,
},
IndexNodeEntry {
key: 4,
pointer: 520,
},
IndexNodeEntry {
key: 16,
pointer: 524,
},
],
};
let meta = super::LocalStoreMeta {
record_count: 3,
specifier_count: 0,
index_node_arity: 16,
data_block_size: 8192,
data_offset: 0,
};
let root_bytes = root.serialize(&meta);
let leaf_bytes = leaf.serialize(&meta);
assert_eq!(IndexNodeType::from(root_bytes[0]), root.node_type);
assert_eq!(IndexNodeType::from(leaf_bytes[0]), leaf.node_type);
assert_eq!(root_bytes[2..10], root.children[0].key.to_be_bytes());
assert_eq!(root_bytes[10..18], root.children[0].pointer.to_be_bytes());
assert!(root_bytes.iter().skip(18).all(|x| *x == 0u8));
let mut cnt = 2;
for child in leaf.children {
assert_eq!(leaf_bytes[cnt..(cnt + 8)], child.key.to_be_bytes());
assert_eq!(
leaf_bytes[(cnt + 8)..(cnt + 16)],
child.pointer.to_be_bytes()
);
cnt += 16;
}
assert!(root_bytes.iter().skip(cnt).all(|x| *x == 0u8));
}
}

View file

@ -39,13 +39,13 @@ impl From<u8> for RecordType {
}
pub trait Store {
fn get_creds(&self, specifier: String, key: String) -> Option<StoreRecord>;
fn get_creds_by_specifier(&self, specifier: String) -> Vec<StoreRecord>;
fn get_creds(&self, specifier: &String, key: &String) -> Option<StoreRecord>;
fn get_creds_by_specifier(&self, specifier: &String) -> Vec<StoreRecord>;
fn store_creds(
&self,
specifier: String,
key: String,
value: Vec<u8>,
specifier: &String,
key: &String,
value: &Vec<u8>,
r#type: RecordType,
meta: Option<String>,
);

View file

@ -1,6 +1,6 @@
use reqwest::header::HeaderValue;
use super::{Store, StoreRecord, RecordType};
use super::{RecordType, Store, StoreRecord};
pub struct ServerStore {
address: String,
@ -41,19 +41,19 @@ impl ServerStore {
}
impl Store for ServerStore {
fn get_creds(&self, specifier: String, key: String) -> Option<StoreRecord> {
fn get_creds(&self, specifier: &String, key: &String) -> Option<StoreRecord> {
todo!()
}
fn get_creds_by_specifier(&self, specifier: String) -> Vec<StoreRecord> {
fn get_creds_by_specifier(&self, specifier: &String) -> Vec<StoreRecord> {
todo!()
}
fn store_creds(
&self,
specifier: String,
key: String,
value: Vec<u8>,
specifier: &String,
key: &String,
value: &Vec<u8>,
r#type: RecordType,
meta: Option<String>,
) {