Skip to main content

Stats

Struct Stats 

Source
pub struct Stats {
Show 20 fields pub commits: u64, pub wakes: u64, pub user_bytes: u64, pub gc_bytes: u64, pub parity_bytes: u64, pub marker_bytes: u64, pub ckpt_bytes: u64, pub erases: u64, pub segments: u32, pub segments_sealed: u32, pub segments_free: u32, pub ckpt_seg_seq: u64, pub cur_seg_seq: u64, pub gc_scanned: u64, pub gc_relocated: u64, pub gc_open_failed: u64, pub gc_segments_freed: u64, pub hot_head: u32, pub cold_head: u32, pub seg_end: u32,
}

Fields§

§commits: u64§wakes: u64§user_bytes: u64

Record bytes the application asked to store (framing + key + value).

§gc_bytes: u64

Record bytes rewritten by GC relocation.

§parity_bytes: u64

Parity pages programmed.

§marker_bytes: u64

Commit-marker pages programmed.

§ckpt_bytes: u64

Checkpoint pages programmed by epoch seals.

§erases: u64§segments: u32

Segments in the table (0 when unmanaged).

§segments_sealed: u32

Segments currently reclaimable-by-GC (Sealed).

§segments_free: u32

Segments currently free.

§ckpt_seg_seq: u64

Reclaim watermark: a sealed segment is eligible when its allocation number is below this.

§cur_seg_seq: u64

Newest segment allocation number handed out.

§gc_scanned: u64

Records visited by compaction scans.

§gc_relocated: u64

Records compaction found live and relocated.

§gc_open_failed: u64

Records compaction could not decrypt (data loss if nonzero).

§gc_segments_freed: u64

Segments reclaimed.

§hot_head: u32

Hot log head offset.

§cold_head: u32

Cold log head offset.

§seg_end: u32

First offset past the last segment.

Implementations§

Source§

impl Stats

Source

pub fn flash_bytes(&self) -> u64

Total bytes programmed to flash across every bucket.

Examples found in repository?
examples/slate_wa_buckets.rs (line 85)
19fn main() {
20    let root = std::env::temp_dir().join(format!("slate_wa_{}", std::process::id()));
21    let _ = std::fs::remove_dir_all(&root);
22
23    println!("# SLATE paper measurement: write-amplification byte buckets");
24    println!(
25        "# geometry=esp32c3 capacity={CAPACITY} page=256 block=4096 \
26         val_len={VAL_LEN} n_distinct_keys={N_DISTINCT} n_ops={N_OPS} \
27         durability=Full compaction=explicit"
28    );
29    println!(
30        "b_commit,ops_accepted,acked_seq,live_keys,commits,wakes,\
31         user_bytes,gc_bytes,parity_bytes,marker_bytes,ckpt_bytes,\
32         total_bytes,erases,gc_scanned,gc_relocated,gc_open_failed,\
33         gc_segments_freed,segments,segments_sealed,segments_free,\
34         hot_head,cold_head,seg_end,wa"
35    );
36
37    for &b in &[1u32, 2, 4, 8, 16, 27, 32, 64, 128] {
38        let dir = root.join(format!("b{b}"));
39        std::fs::create_dir_all(&dir).unwrap();
40
41        let opts = Options {
42            capacity: CAPACITY,
43            b_commit: b,
44            auto_b: false,
45            staleness_budget_ms: 1000,
46            n_keys: 2048,
47            profile: Profile::Esp32,
48            durability: slate_kv::file_flash::Durability::Full,
49        };
50        let db = Db::open(&dir, KeySource::Bytes([0x42; 32]), opts).unwrap();
51
52        let val = vec![0xA5u8; VAL_LEN];
53        let mut ops = 0usize;
54        for i in 0..N_OPS {
55            let key = format!("sensor_{:06}", i % N_DISTINCT);
56            if db.put(key.as_bytes(), &val).is_err() {
57                break;
58            }
59            ops = i + 1;
60        }
61        let _ = db.commit();
62        let _ = db.compact();
63
64        let s = db.stats();
65        let wa = match s.write_amplification() {
66            Some(w) => w,
67            None => {
68                eprintln!("b_commit={b}: nothing measured");
69                continue;
70            }
71        };
72        println!(
73            "{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{:.4}",
74            b,
75            ops,
76            db.acked_seq(),
77            db.len(),
78            s.commits,
79            s.wakes,
80            s.user_bytes,
81            s.gc_bytes,
82            s.parity_bytes,
83            s.marker_bytes,
84            s.ckpt_bytes,
85            s.flash_bytes(),
86            s.erases,
87            s.gc_scanned,
88            s.gc_relocated,
89            s.gc_open_failed,
90            s.gc_segments_freed,
91            s.segments,
92            s.segments_sealed,
93            s.segments_free,
94            s.hot_head,
95            s.cold_head,
96            s.seg_end,
97            wa
98        );
99        drop(db);
100        let _ = std::fs::remove_dir_all(&dir);
101    }
102    let _ = std::fs::remove_dir_all(&root);
103}
Source

pub fn write_amplification(&self) -> Option<f64>

Write amplification: flash bytes programmed per byte of user data.

None when nothing has been written yet. A workload that has not been measured and one with no overhead are different claims, so this must not silently report 1.0 for the former.

Examples found in repository?
examples/slate_wa_buckets.rs (line 65)
19fn main() {
20    let root = std::env::temp_dir().join(format!("slate_wa_{}", std::process::id()));
21    let _ = std::fs::remove_dir_all(&root);
22
23    println!("# SLATE paper measurement: write-amplification byte buckets");
24    println!(
25        "# geometry=esp32c3 capacity={CAPACITY} page=256 block=4096 \
26         val_len={VAL_LEN} n_distinct_keys={N_DISTINCT} n_ops={N_OPS} \
27         durability=Full compaction=explicit"
28    );
29    println!(
30        "b_commit,ops_accepted,acked_seq,live_keys,commits,wakes,\
31         user_bytes,gc_bytes,parity_bytes,marker_bytes,ckpt_bytes,\
32         total_bytes,erases,gc_scanned,gc_relocated,gc_open_failed,\
33         gc_segments_freed,segments,segments_sealed,segments_free,\
34         hot_head,cold_head,seg_end,wa"
35    );
36
37    for &b in &[1u32, 2, 4, 8, 16, 27, 32, 64, 128] {
38        let dir = root.join(format!("b{b}"));
39        std::fs::create_dir_all(&dir).unwrap();
40
41        let opts = Options {
42            capacity: CAPACITY,
43            b_commit: b,
44            auto_b: false,
45            staleness_budget_ms: 1000,
46            n_keys: 2048,
47            profile: Profile::Esp32,
48            durability: slate_kv::file_flash::Durability::Full,
49        };
50        let db = Db::open(&dir, KeySource::Bytes([0x42; 32]), opts).unwrap();
51
52        let val = vec![0xA5u8; VAL_LEN];
53        let mut ops = 0usize;
54        for i in 0..N_OPS {
55            let key = format!("sensor_{:06}", i % N_DISTINCT);
56            if db.put(key.as_bytes(), &val).is_err() {
57                break;
58            }
59            ops = i + 1;
60        }
61        let _ = db.commit();
62        let _ = db.compact();
63
64        let s = db.stats();
65        let wa = match s.write_amplification() {
66            Some(w) => w,
67            None => {
68                eprintln!("b_commit={b}: nothing measured");
69                continue;
70            }
71        };
72        println!(
73            "{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{:.4}",
74            b,
75            ops,
76            db.acked_seq(),
77            db.len(),
78            s.commits,
79            s.wakes,
80            s.user_bytes,
81            s.gc_bytes,
82            s.parity_bytes,
83            s.marker_bytes,
84            s.ckpt_bytes,
85            s.flash_bytes(),
86            s.erases,
87            s.gc_scanned,
88            s.gc_relocated,
89            s.gc_open_failed,
90            s.gc_segments_freed,
91            s.segments,
92            s.segments_sealed,
93            s.segments_free,
94            s.hot_head,
95            s.cold_head,
96            s.seg_end,
97            wa
98        );
99        drop(db);
100        let _ = std::fs::remove_dir_all(&dir);
101    }
102    let _ = std::fs::remove_dir_all(&root);
103}

Trait Implementations§

Source§

impl Clone for Stats

Source§

fn clone(&self) -> Stats

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Stats

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Stats

Source§

fn default() -> Stats

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Stats

§

impl RefUnwindSafe for Stats

§

impl Send for Stats

§

impl Sync for Stats

§

impl Unpin for Stats

§

impl UnsafeUnpin for Stats

§

impl UnwindSafe for Stats

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.