#[cfg(feature = "atomic")]
use bstack::BStack;
#[cfg(feature = "atomic")]
use std::io;
#[cfg(feature = "atomic")]
fn show(label: &str, stack: &BStack) -> io::Result<()> {
println!("{label}: {:?}", String::from_utf8_lossy(&stack.peek(0)?));
Ok(())
}
#[cfg(feature = "atomic")]
fn main() -> io::Result<()> {
let path = "atomic_ops_example.bstack";
let _ = std::fs::remove_file(path);
let stack = BStack::open(path)?;
stack.push(b"[ok] start\n")?;
stack.push(b"[ok] login\n")?;
stack.push(b"[ok] fetch\n")?;
show("initial ", &stack)?;
stack.replace(11, |old| old.to_ascii_uppercase())?;
show("after replace", &stack)?;
stack.atrunc(11, b"[ok] store\n")?;
show("after atrunc ", &stack)?;
let removed = stack.splice(11, b"[ok] flush\n")?;
println!("splice removed {:?}", String::from_utf8_lossy(&removed));
show("after splice ", &stack)?;
let mut old_line = [0u8; 11];
stack.splice_into(&mut old_line, b"[ok] close\n")?;
println!(
"splice_into removed {:?}",
String::from_utf8_lossy(&old_line)
);
show("after s_into ", &stack)?;
let snap = stack.len()?;
let pushed1 = stack.try_extend(snap, b"[ok] retry\n")?;
let pushed2 = stack.try_extend(snap, b"[ok] retry\n")?; println!("try_extend: first={pushed1} second={pushed2}");
show("after t_ext ", &stack)?;
let snap = stack.len()?;
let ok1 = stack.try_discard(snap, 11)?;
let ok2 = stack.try_discard(snap, 11)?; println!("try_discard: first={ok1} second={ok2}");
show("after t_disc ", &stack)?;
#[cfg(feature = "set")]
{
let status_off = stack.push(&[0u8; 8])?;
println!("status record at offset {status_off}");
let prev = stack.swap(status_off, b"RUN\x00")?;
println!("swap wrote 'RUN\\0', got back {:02x?}", prev);
let ok_cas1 = stack.cas(status_off, b"RUN\x00", b"DONE")?;
let ok_cas2 = stack.cas(status_off, b"RUN\x00", b"FAIL")?;
println!("cas: first={ok_cas1} second={ok_cas2}");
println!(
"tag now: {:?}",
String::from_utf8_lossy(&stack.get(status_off, status_off + 4)?)
);
stack.process(status_off, status_off + 8, |buf| {
let n = u32::from_le_bytes([buf[4], buf[5], buf[6], buf[7]]);
buf[4..8].copy_from_slice(&(n + 1).to_le_bytes());
})?;
let record = stack.get(status_off, status_off + 8)?;
let counter = u32::from_le_bytes([record[4], record[5], record[6], record[7]]);
println!(
"after process: tag={:?} counter={counter}",
String::from_utf8_lossy(&record[..4])
);
}
Ok(())
}
#[cfg(not(feature = "atomic"))]
fn main() {
eprintln!("This example requires the `atomic` feature.");
eprintln!("Run with: cargo run --example atomic_ops --features atomic");
}