aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock90
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs53
3 files changed, 134 insertions, 10 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5837ea0..f9caa86 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,12 +1,53 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
+name = "ahash"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3"
+dependencies = [
+ "const-random",
+]
+
+[[package]]
+name = "autocfg"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+
+[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "const-random"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a"
+dependencies = [
+ "const-random-macro",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "const-random-macro"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a"
+dependencies = [
+ "getrandom",
+ "proc-macro-hack",
+]
+
+[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -16,8 +57,57 @@ dependencies = [
]
[[package]]
+name = "getrandom"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
name = "growth-ring"
version = "0.1.0"
dependencies = [
"crc",
+ "lru",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
+dependencies = [
+ "ahash",
+ "autocfg",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
+
+[[package]]
+name = "lru"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28e0c685219cd60e49a2796bba7e4fe6523e10daca4fd721e84e7f905093d60c"
+dependencies = [
+ "hashbrown",
]
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
diff --git a/Cargo.toml b/Cargo.toml
index 0899509..fb77a6a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,6 +8,7 @@ edition = "2018"
[dependencies]
crc = "1.8.1"
+lru = "0.5.1"
[lib]
name = "growthring"
diff --git a/src/lib.rs b/src/lib.rs
index d6a1e12..e4ae0ea 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
#[repr(u8)]
enum WALRingType {
+ Null = 0x0,
Full,
First,
Middle,
@@ -24,29 +25,59 @@ pub struct WALState {
pub file_nbit: u8,
}
-pub struct WALWriter {
+pub trait WALFile {
+ fn allocate(&self, offset: u64, length: usize);
+ fn write(&self, offset: u64, data: Box<[u8]>);
+ fn read(&self, offset: u64, length: usize) -> Box<[u8]>;
+}
+
+pub trait WALStore {
+ fn open_file(&self, filename: &str, touch: bool) -> Option<Box<dyn WALFile>>;
+ fn remove_file(&self, filename: &str) -> bool;
+ fn scan_files(&self) -> Box<[&str]>;
+}
+
+struct WALFilePool<F: WALStore> {
+ store: F,
+ handles: lru::LruCache<u64, Box<dyn WALFile>>,
+ file_size: u64
+}
+
+impl<F: WALStore> WALFilePool<F> {
+ fn new(store: F, file_size: u64, cache_size: usize) -> Self {
+ WALFilePool {
+ store,
+ handles: lru::LruCache::new(cache_size),
+ file_size,
+ }
+ }
+ fn write(&mut self, offset: u64, data: Box<[u8]>) {
+ }
+}
+
+pub struct WALWriter<F: WALStore> {
state: WALState,
+ file_pool: WALFilePool<F>,
block_buffer: Box<[u8]>,
block_size: u32,
- file_size: u64,
}
-impl WALWriter {
- pub fn new(state: WALState) -> Self {
+impl<F: WALStore> WALWriter<F> {
+ pub fn new(state: WALState, wal_store: F, cache_size: usize) -> Self {
let mut b = Vec::new();
let block_size = 1 << (state.block_nbit as u32);
let file_size = 1 << (state.file_nbit as u64);
b.resize(block_size as usize, 0);
WALWriter{
state,
+ file_pool: WALFilePool::new(wal_store, file_size, cache_size),
block_buffer: b.into_boxed_slice(),
block_size,
- file_size,
}
}
- pub fn grow(&mut self, records: &[Box<[u8]>]) -> Vec<WALWrite> {
- let mut res = Vec::new();
+ pub fn grow(&mut self, records: &[Box<[u8]>]) {
+ let mut writes = Vec::new();
let msize = std::mem::size_of::<WALRingBlob>() as u32;
// the global offest of the begining of the block
// the start of the unwritten data
@@ -92,7 +123,7 @@ impl WALWriter {
bbuff_cur = self.block_size;
}
if bbuff_cur == self.block_size {
- res.push((self.state.last,
+ writes.push((self.state.last,
self.block_buffer[bbuff_start as usize..]
.to_vec().into_boxed_slice()));
self.state.last += (self.block_size - bbuff_start) as u64;
@@ -102,12 +133,14 @@ impl WALWriter {
}
}
if bbuff_cur > bbuff_start {
- res.push((self.state.last,
+ writes.push((self.state.last,
self.block_buffer[bbuff_start as usize..bbuff_cur as usize]
.to_vec().into_boxed_slice()));
self.state.last += (bbuff_cur - bbuff_start) as u64;
}
- res
+ for (off, w) in writes.into_iter() {
+ self.file_pool.write(off, w)
+ }
}
}