aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock33
-rw-r--r--Cargo.toml2
-rw-r--r--examples/demo1.rs77
3 files changed, 102 insertions, 10 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f20c53d..8aec840 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -25,12 +25,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
+name = "cc"
+version = "1.0.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
+
+[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -82,7 +94,9 @@ version = "0.1.0"
dependencies = [
"crc",
"hex",
+ "libc",
"lru",
+ "nix",
"scan_fmt",
]
@@ -130,6 +144,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
+name = "nix"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
+dependencies = [
+ "bitflags",
+ "cc",
+ "cfg-if",
+ "libc",
+ "void",
+]
+
+[[package]]
name = "proc-macro-hack"
version = "0.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -172,6 +199,12 @@ dependencies = [
]
[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 2915a84..4193862 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,8 @@ scan_fmt = "0.2.5"
[dev-dependencies]
hex = "0.4.2"
+libc = "0.2.44"
+nix = "0.17.0"
[lib]
name = "growthring"
diff --git a/examples/demo1.rs b/examples/demo1.rs
index 0f50ec3..536aba2 100644
--- a/examples/demo1.rs
+++ b/examples/demo1.rs
@@ -1,27 +1,84 @@
use growthring::{WALFile, WALStore, WALPos, WALBytes, WALLoader, WALWriter};
-struct WALFileFake {
- filename: String
+use std::os::unix::io::RawFd;
+use nix::Error::Sys;
+use nix::errno::Errno;
+use nix::unistd::{close, mkdir, sysconf, SysconfVar};
+use nix::fcntl::{open, openat, OFlag, fallocate, FallocateFlags};
+use nix::sys::{stat::Mode, uio::pwrite};
+use libc::off_t;
+
+struct WALFileTest {
+ filename: String,
+ fd: RawFd,
+}
+
+impl WALFileTest {
+ fn new(rootfd: RawFd, filename: &str) -> Self {
+ let fd = openat(rootfd, filename,
+ OFlag::O_CREAT | OFlag::O_RDWR,
+ Mode::S_IRUSR | Mode::S_IWUSR).unwrap();
+ let filename = filename.to_string();
+ WALFileTest {
+ filename,
+ fd,
+ }
+ }
}
-impl WALFile for WALFileFake {
+impl Drop for WALFileTest {
+ fn drop(&mut self) {
+ close(self.fd).unwrap();
+ }
+}
+
+impl WALFile for WALFileTest {
fn allocate(&self, offset: WALPos, length: usize) {
println!("{}.allocate(offset=0x{:x}, end=0x{:x})", self.filename, offset, offset + length as u64);
+ fallocate(self.fd, FallocateFlags::FALLOC_FL_ZERO_RANGE, offset as off_t, length as off_t);
}
fn write(&self, offset: WALPos, data: WALBytes) {
- println!("{}.write(offset=0x{:x}, end=0x{:x}, data=0x{})", self.filename, offset, offset + data.len() as u64, hex::encode(data));
+ println!("{}.write(offset=0x{:x}, end=0x{:x}, data=0x{})",
+ self.filename, offset, offset + data.len() as u64, hex::encode(&data));
+ pwrite(self.fd, &*data, offset as off_t);
}
fn read(&self, offset: WALPos, length: usize) -> WALBytes {
- Vec::new().into_boxed_slice()
+ unreachable!()
+ }
+}
+
+struct WALStoreTest {
+ rootfd: RawFd
+}
+
+impl WALStoreTest {
+ fn new(wal_dir: &str, truncate: bool) -> Self {
+ if truncate {
+ let _ = std::fs::remove_dir_all(wal_dir);
+ }
+ match mkdir(wal_dir, Mode::S_IRUSR | Mode::S_IWUSR | Mode::S_IXUSR) {
+ Err(e) => if truncate { panic!("error while creating directory: {}", e) },
+ Ok(_) => ()
+ }
+ let rootfd = match open(wal_dir, OFlag::O_DIRECTORY | OFlag::O_PATH, Mode::empty()) {
+ Ok(fd) => fd,
+ Err(_) => panic!("error while opening the DB")
+ };
+ WALStoreTest { rootfd }
+ }
+}
+
+impl Drop for WALStoreTest {
+ fn drop(&mut self) {
+ close(self.rootfd).unwrap();
}
}
-struct WALStoreFake;
-impl WALStore for WALStoreFake {
+impl WALStore for WALStoreTest {
fn open_file(&self, filename: &str, touch: bool) -> Option<Box<dyn WALFile>> {
println!("open_file(filename={}, touch={}", filename, touch);
let filename = filename.to_string();
- Some(Box::new(WALFileFake{ filename }))
+ Some(Box::new(WALFileTest::new(self.rootfd, &filename)))
}
fn remove_file(&self, filename: &str) -> bool {
println!("remove_file(filename={})", filename);
@@ -36,7 +93,7 @@ impl WALStore for WALStoreFake {
}
}
-fn test(records: Vec<String>, wal: &mut WALWriter<WALStoreFake>) {
+fn test(records: Vec<String>, wal: &mut WALWriter<WALStoreTest>) {
let records: Vec<WALBytes> = records.into_iter().map(|s| s.into_bytes().into_boxed_slice()).collect();
let ret = wal.grow(&records);
for ring_id in ret.iter() {
@@ -45,7 +102,7 @@ fn test(records: Vec<String>, wal: &mut WALWriter<WALStoreFake>) {
}
fn main() {
- let store = WALStoreFake;
+ let store = WALStoreTest::new("./wal_demo1", true);
let mut wal = WALLoader::new(store, 9, 8, 1000).recover();
for _ in 0..3 {
test(["hi", "hello", "lol"].iter().map(|s| s.to_string()).collect::<Vec<String>>(), &mut wal)