pub struct MemMapTransaction<'a, T: Sized + Clone + PartialEq> { /* private fields */ }Expand description
Context for grouping multiple conditional writes into a single atomic operation
Multi-slot mutations are staged in MemMapTransaction with optimistic concurrency
preconditions. At commit time, all target slot locks are acquired in strictly
ascending order, each slot is verified against its expected value, and if all match, all
updates are applied under a single epoch
If any slot fails verification, the transaction aborts with zero mutations, returning
[err::CAS] with the index of the first conflicting slot so the caller can retry
§Example
use frozen_core::memmap::{MemMap, MemMapCfg};
use std::time::Duration;
let dir = tempfile::tempdir().unwrap();
let cfg = MemMapCfg {
module_id: 1,
path: dir.path().join("tx_struct_demo.bin"),
version: 1,
initial_t: 512,
sync_interval: Some(Duration::from_millis(100)),
page_size: None,
};
let mmap = MemMap::<u64>::new(cfg).unwrap();
let mut tx = mmap.new_tx();
tx.write(&0u64, &42u64, 0).unwrap();
tx.write(&0u64, &84u64, 2).unwrap();
let ticket = tx.commit().unwrap();
assert_eq!(mmap.read(0, |v| *v).unwrap(), 42u64);
assert_eq!(mmap.read(2, |v| *v).unwrap(), 84u64);Implementations§
Source§impl<T> MemMapTransaction<'_, T>
impl<T> MemMapTransaction<'_, T>
Sourcepub fn write(
&mut self,
expected: &T,
new: &T,
index: usize,
) -> FrozenResult<&mut Self>
pub fn write( &mut self, expected: &T, new: &T, index: usize, ) -> FrozenResult<&mut Self>
Stages a conditional write of new at index requiring expected as the current slot
value
§Requirements
- Writes must be staged in strictly increasing index order (
index > previous_index) - Duplicate indices in the same transaction return an error
indexmust not exceed mapping bounds
§Example
use frozen_core::memmap::{MemMap, MemMapCfg};
use std::time::Duration;
let dir = tempfile::tempdir().unwrap();
let cfg = MemMapCfg {
module_id: 1,
path: dir.path().join("tx_write_demo.bin"),
version: 1,
initial_t: 512,
sync_interval: Some(Duration::from_millis(100)),
page_size: None,
};
let mmap = MemMap::<u64>::new(cfg).unwrap();
let mut tx = mmap.new_tx();
tx.write(&0u64, &111u64, 0).unwrap();
tx.write(&0u64, &222u64, 1).unwrap();
// Staging an out-of-order or duplicate index fails
assert!(tx.write(&0u64, &333u64, 1).is_err());
assert!(tx.write(&0u64, &333u64, 0).is_err());Sourcepub fn commit(self) -> FrozenResult<AckTicket>
pub fn commit(self) -> FrozenResult<AckTicket>
Commits all staged writes atomically under a single durability epoch
Acquires exclusive locks for all affected slots in order; if all slots match their expected
values, updates are applied, the durable epoch advances once, and an AckTicket is
returned
If any slot differs from expected, all locks are released without modifying any data, and
[err::CAS] is returned with context identifying the conflicting slot index
§Example
use frozen_core::memmap::{MemMap, MemMapCfg};
use std::time::Duration;
let dir = tempfile::tempdir().unwrap();
let cfg = MemMapCfg {
module_id: 1,
path: dir.path().join("tx_commit_demo.bin"),
version: 1,
initial_t: 512,
sync_interval: Some(Duration::from_millis(100)),
page_size: None,
};
let mmap = MemMap::<u64>::new(cfg).unwrap();
let mut tx = mmap.new_tx();
tx.write(&0u64, &100u64, 0).unwrap();
tx.write(&0u64, &200u64, 1).unwrap();
let ticket = tx.commit().unwrap();
assert_eq!(mmap.read(0, |v| *v).unwrap(), 100u64);
assert_eq!(mmap.read(1, |v| *v).unwrap(), 200u64);Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of staged operations in this transaction
§Example
use frozen_core::memmap::{MemMap, MemMapCfg};
let dir = tempfile::tempdir().unwrap();
let cfg = MemMapCfg {
module_id: 1,
path: dir.path().join("tx_len_demo.bin"),
version: 1,
initial_t: 512,
sync_interval: None,
page_size: None,
};
let mmap = MemMap::<u64>::new(cfg).unwrap();
let mut tx = mmap.new_tx();
assert_eq!(tx.len(), 0);
tx.write(&0u64, &10u64, 0).unwrap();
assert_eq!(tx.len(), 1);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if no operations have been staged in this transaction
§Example
use frozen_core::memmap::{MemMap, MemMapCfg};
let dir = tempfile::tempdir().unwrap();
let cfg = MemMapCfg {
module_id: 1,
path: dir.path().join("tx_empty_demo.bin"),
version: 1,
initial_t: 512,
sync_interval: None,
page_size: None,
};
let mmap = MemMap::<u64>::new(cfg).unwrap();
let tx = mmap.new_tx();
assert!(tx.is_empty());