pub struct Bump { /* private fields */ }Expand description
Fixed-capacity bump-pointer arena.
Implementations§
Source§impl Bump
impl Bump
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
New arena, pre-allocating a single chunk of capacity bytes
(promoted to a 64-byte floor and 16-byte alignment).
Examples found in repository?
examples/growth_main.rs (line 99)
76fn main() -> ExitCode {
77 let mut raw = String::new();
78 if io::stdin().read_to_string(&mut raw).is_err() {
79 eprintln!("growth_main: failed to read stdin");
80 return ExitCode::FAILURE;
81 }
82 let mut map = BTreeMap::new();
83 for line in raw.lines() {
84 let line = line.trim();
85 if line.is_empty() || line.starts_with('#') {
86 continue;
87 }
88 if let Some((k, v)) = line.split_once('=') {
89 map.insert(k.trim().to_string(), v.trim().to_string());
90 }
91 }
92 let rounds = parse_usize(&map, "rounds", 50);
93 let allocs_per_round = parse_usize(&map, "allocs_per_round", 20_000);
94
95 // Buffer sized to hold one round's allocations (u64 + alignment) with headroom
96 // - the base Bump is fixed-capacity and panics rather than growing.
97 let capacity = allocs_per_round * 16 + 4096;
98 let mut recipe = ArenaChurn {
99 arena: Bump::with_capacity(capacity),
100 rounds,
101 allocs_per_round,
102 };
103 let report = grow(&mut recipe, "rust");
104
105 if growth_to_json(&report, &mut io::stdout().lock()).is_err() {
106 eprintln!("growth_main: failed to write json");
107 return ExitCode::FAILURE;
108 }
109 ExitCode::SUCCESS
110}More examples
examples/sample_app.rs (line 43)
41fn base_per_tick_scratch() {
42 println!("== base: per-tick order-book scratch ==");
43 let mut scratch = Bump::with_capacity(4096);
44 let cap = scratch.capacity();
45
46 let ticks: [&[(u64, u32, bool)]; 2] = [
47 &[
48 (9998, 5, true),
49 (9997, 8, true),
50 (10002, 4, false),
51 (10003, 9, false),
52 ],
53 &[(9999, 3, true), (10001, 7, false)],
54 ];
55
56 for (t, updates) in ticks.iter().enumerate() {
57 let (mut best_bid, mut best_ask) = (0u64, u64::MAX);
58 let (mut bid_qty, mut ask_qty) = (0u64, 0u64);
59 for &(price, qty, is_bid) in updates.iter() {
60 let level = scratch.alloc_copy(Level {
61 price_ticks: price,
62 qty,
63 });
64 if is_bid {
65 best_bid = best_bid.max(level.price_ticks);
66 bid_qty += level.qty as u64;
67 } else {
68 best_ask = best_ask.min(level.price_ticks);
69 ask_qty += level.qty as u64;
70 }
71 }
72 let mid = (best_bid + best_ask) / 2;
73 let imbalance = bid_qty as i64 - ask_qty as i64;
74 println!(
75 " tick {t}: {} levels, mid={mid} imbalance={imbalance:+} used={}B",
76 updates.len(),
77 scratch.used(),
78 );
79 assert!(scratch.used() > 0, "levels consumed scratch");
80 scratch.reset();
81 assert_eq!(scratch.used(), 0, "reset rewinds the cursor");
82 assert_eq!(scratch.capacity(), cap, "no reallocation between ticks");
83 }
84 println!(" -> steady-state chunk stays at {cap}B across all ticks");
85}Sourcepub fn alloc_copy<T: Copy>(&mut self, value: T) -> &mut T
pub fn alloc_copy<T: Copy>(&mut self, value: T) -> &mut T
Allocate a Copy value. Panics if the arena is out of room.
Examples found in repository?
More examples
examples/sample_app.rs (lines 60-63)
41fn base_per_tick_scratch() {
42 println!("== base: per-tick order-book scratch ==");
43 let mut scratch = Bump::with_capacity(4096);
44 let cap = scratch.capacity();
45
46 let ticks: [&[(u64, u32, bool)]; 2] = [
47 &[
48 (9998, 5, true),
49 (9997, 8, true),
50 (10002, 4, false),
51 (10003, 9, false),
52 ],
53 &[(9999, 3, true), (10001, 7, false)],
54 ];
55
56 for (t, updates) in ticks.iter().enumerate() {
57 let (mut best_bid, mut best_ask) = (0u64, u64::MAX);
58 let (mut bid_qty, mut ask_qty) = (0u64, 0u64);
59 for &(price, qty, is_bid) in updates.iter() {
60 let level = scratch.alloc_copy(Level {
61 price_ticks: price,
62 qty,
63 });
64 if is_bid {
65 best_bid = best_bid.max(level.price_ticks);
66 bid_qty += level.qty as u64;
67 } else {
68 best_ask = best_ask.min(level.price_ticks);
69 ask_qty += level.qty as u64;
70 }
71 }
72 let mid = (best_bid + best_ask) / 2;
73 let imbalance = bid_qty as i64 - ask_qty as i64;
74 println!(
75 " tick {t}: {} levels, mid={mid} imbalance={imbalance:+} used={}B",
76 updates.len(),
77 scratch.used(),
78 );
79 assert!(scratch.used() > 0, "levels consumed scratch");
80 scratch.reset();
81 assert_eq!(scratch.used(), 0, "reset rewinds the cursor");
82 assert_eq!(scratch.capacity(), cap, "no reallocation between ticks");
83 }
84 println!(" -> steady-state chunk stays at {cap}B across all ticks");
85}Sourcepub fn try_alloc_copy<T: Copy>(&mut self, value: T) -> Option<&mut T>
pub fn try_alloc_copy<T: Copy>(&mut self, value: T) -> Option<&mut T>
Fallible alloc. Returns None if the arena can’t fit the value
at its natural alignment.
Sourcepub fn alloc_raw(&mut self, layout: Layout) -> *mut u8
pub fn alloc_raw(&mut self, layout: Layout) -> *mut u8
Allocate layout.size() bytes aligned to layout.align().
Panics if the request doesn’t fit.
Sourcepub fn try_alloc_raw(&mut self, layout: Layout) -> Option<*mut u8>
pub fn try_alloc_raw(&mut self, layout: Layout) -> Option<*mut u8>
Fallible raw alloc. Returns None if the request doesn’t fit.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Rewind to empty. The buffer is retained for reuse.
Examples found in repository?
More examples
examples/sample_app.rs (line 80)
41fn base_per_tick_scratch() {
42 println!("== base: per-tick order-book scratch ==");
43 let mut scratch = Bump::with_capacity(4096);
44 let cap = scratch.capacity();
45
46 let ticks: [&[(u64, u32, bool)]; 2] = [
47 &[
48 (9998, 5, true),
49 (9997, 8, true),
50 (10002, 4, false),
51 (10003, 9, false),
52 ],
53 &[(9999, 3, true), (10001, 7, false)],
54 ];
55
56 for (t, updates) in ticks.iter().enumerate() {
57 let (mut best_bid, mut best_ask) = (0u64, u64::MAX);
58 let (mut bid_qty, mut ask_qty) = (0u64, 0u64);
59 for &(price, qty, is_bid) in updates.iter() {
60 let level = scratch.alloc_copy(Level {
61 price_ticks: price,
62 qty,
63 });
64 if is_bid {
65 best_bid = best_bid.max(level.price_ticks);
66 bid_qty += level.qty as u64;
67 } else {
68 best_ask = best_ask.min(level.price_ticks);
69 ask_qty += level.qty as u64;
70 }
71 }
72 let mid = (best_bid + best_ask) / 2;
73 let imbalance = bid_qty as i64 - ask_qty as i64;
74 println!(
75 " tick {t}: {} levels, mid={mid} imbalance={imbalance:+} used={}B",
76 updates.len(),
77 scratch.used(),
78 );
79 assert!(scratch.used() > 0, "levels consumed scratch");
80 scratch.reset();
81 assert_eq!(scratch.used(), 0, "reset rewinds the cursor");
82 assert_eq!(scratch.capacity(), cap, "no reallocation between ticks");
83 }
84 println!(" -> steady-state chunk stays at {cap}B across all ticks");
85}Sourcepub fn used(&self) -> usize
pub fn used(&self) -> usize
Bytes used so far in the current chunk.
Examples found in repository?
More examples
examples/sample_app.rs (line 77)
41fn base_per_tick_scratch() {
42 println!("== base: per-tick order-book scratch ==");
43 let mut scratch = Bump::with_capacity(4096);
44 let cap = scratch.capacity();
45
46 let ticks: [&[(u64, u32, bool)]; 2] = [
47 &[
48 (9998, 5, true),
49 (9997, 8, true),
50 (10002, 4, false),
51 (10003, 9, false),
52 ],
53 &[(9999, 3, true), (10001, 7, false)],
54 ];
55
56 for (t, updates) in ticks.iter().enumerate() {
57 let (mut best_bid, mut best_ask) = (0u64, u64::MAX);
58 let (mut bid_qty, mut ask_qty) = (0u64, 0u64);
59 for &(price, qty, is_bid) in updates.iter() {
60 let level = scratch.alloc_copy(Level {
61 price_ticks: price,
62 qty,
63 });
64 if is_bid {
65 best_bid = best_bid.max(level.price_ticks);
66 bid_qty += level.qty as u64;
67 } else {
68 best_ask = best_ask.min(level.price_ticks);
69 ask_qty += level.qty as u64;
70 }
71 }
72 let mid = (best_bid + best_ask) / 2;
73 let imbalance = bid_qty as i64 - ask_qty as i64;
74 println!(
75 " tick {t}: {} levels, mid={mid} imbalance={imbalance:+} used={}B",
76 updates.len(),
77 scratch.used(),
78 );
79 assert!(scratch.used() > 0, "levels consumed scratch");
80 scratch.reset();
81 assert_eq!(scratch.used(), 0, "reset rewinds the cursor");
82 assert_eq!(scratch.capacity(), cap, "no reallocation between ticks");
83 }
84 println!(" -> steady-state chunk stays at {cap}B across all ticks");
85}Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Total capacity of the single backing chunk.
Examples found in repository?
examples/sample_app.rs (line 44)
41fn base_per_tick_scratch() {
42 println!("== base: per-tick order-book scratch ==");
43 let mut scratch = Bump::with_capacity(4096);
44 let cap = scratch.capacity();
45
46 let ticks: [&[(u64, u32, bool)]; 2] = [
47 &[
48 (9998, 5, true),
49 (9997, 8, true),
50 (10002, 4, false),
51 (10003, 9, false),
52 ],
53 &[(9999, 3, true), (10001, 7, false)],
54 ];
55
56 for (t, updates) in ticks.iter().enumerate() {
57 let (mut best_bid, mut best_ask) = (0u64, u64::MAX);
58 let (mut bid_qty, mut ask_qty) = (0u64, 0u64);
59 for &(price, qty, is_bid) in updates.iter() {
60 let level = scratch.alloc_copy(Level {
61 price_ticks: price,
62 qty,
63 });
64 if is_bid {
65 best_bid = best_bid.max(level.price_ticks);
66 bid_qty += level.qty as u64;
67 } else {
68 best_ask = best_ask.min(level.price_ticks);
69 ask_qty += level.qty as u64;
70 }
71 }
72 let mid = (best_bid + best_ask) / 2;
73 let imbalance = bid_qty as i64 - ask_qty as i64;
74 println!(
75 " tick {t}: {} levels, mid={mid} imbalance={imbalance:+} used={}B",
76 updates.len(),
77 scratch.used(),
78 );
79 assert!(scratch.used() > 0, "levels consumed scratch");
80 scratch.reset();
81 assert_eq!(scratch.used(), 0, "reset rewinds the cursor");
82 assert_eq!(scratch.capacity(), cap, "no reallocation between ticks");
83 }
84 println!(" -> steady-state chunk stays at {cap}B across all ticks");
85}Sourcepub fn total_capacity(&self) -> usize
pub fn total_capacity(&self) -> usize
Backwards-compatible alias for Bump::capacity.
Trait Implementations§
Auto Trait Implementations§
impl !Send for Bump
impl !Sync for Bump
impl Freeze for Bump
impl RefUnwindSafe for Bump
impl Unpin for Bump
impl UnsafeUnpin for Bump
impl UnwindSafe for Bump
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more