use holt::TreeBuilder;
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
struct Inode {
size: u64,
mtime: u64,
mode: u32,
uid: u32,
gid: u32,
nlink: u32,
}
impl Inode {
fn to_bytes(self) -> [u8; 32] {
unsafe { std::mem::transmute(self) }
}
fn from_bytes(b: &[u8]) -> Self {
assert_eq!(b.len(), 32, "inode is 32 bytes");
let mut buf = [0u8; 32];
buf.copy_from_slice(b);
unsafe { std::mem::transmute(buf) }
}
}
fn main() {
println!("=== holt filesystem_meta example ===\n");
let tree = TreeBuilder::new("scratch").memory().open().expect("open");
let now: u64 = 1_715_817_600;
let entries: &[(&[u8], Inode)] = &[
(
b"/home/alice/notes.txt",
Inode {
size: 1024,
mtime: now,
mode: 0o644,
uid: 1000,
gid: 1000,
nlink: 1,
},
),
(
b"/home/alice/photos/sunset.jpg",
Inode {
size: 2_345_678,
mtime: now - 3600,
mode: 0o644,
uid: 1000,
gid: 1000,
nlink: 1,
},
),
(
b"/home/bob/.bashrc",
Inode {
size: 412,
mtime: now - 86_400,
mode: 0o600,
uid: 1001,
gid: 1001,
nlink: 1,
},
),
(
b"/etc/passwd",
Inode {
size: 2_048,
mtime: now - 7 * 86_400,
mode: 0o644,
uid: 0,
gid: 0,
nlink: 1,
},
),
];
for (path, inode) in entries {
tree.put(path, &inode.to_bytes()).unwrap();
}
println!("loaded {} inodes\n", entries.len());
let path: &[u8] = b"/home/alice/photos/sunset.jpg";
let bytes = tree.get(path).unwrap().expect("present");
let i = Inode::from_bytes(&bytes);
let size = i.size;
let mode = i.mode;
let nlink = i.nlink;
println!(
"stat {:?} -> size={size} mode={mode:o} nlink={nlink}",
std::str::from_utf8(path).unwrap(),
);
tree.rename(
b"/home/alice/photos/sunset.jpg",
b"/home/alice/photos/sunset-archived.jpg",
false,
)
.unwrap();
assert!(tree
.get(b"/home/alice/photos/sunset.jpg")
.unwrap()
.is_none());
assert!(tree
.get(b"/home/alice/photos/sunset-archived.jpg")
.unwrap()
.is_some());
println!("renamed: original path gone, new path present");
let prev = tree.delete(b"/home/bob/.bashrc").unwrap();
println!(
"unlink /home/bob/.bashrc -> previous {} bytes",
prev.map(|v| v.len()).unwrap_or(0),
);
tree.checkpoint().unwrap();
println!("\ndone");
}