Struct someday::Transaction
source · pub struct Transaction<'writer, T: Clone> { /* private fields */ }
Expand description
Mutate the data T
directly without going through a Patch
.
This structure is returned by Writer::tx
, and can be seen as a
temporary handle for mutating your data T
.
§Mutable access to T
Transaction
gives direct mutable access to the Writer
’s inner data T
via:
Each call to any of these functions will increment the Timestamp
by 1
, regardless if the data was changed or not.
§Drop
After Transaction
has been Transaction::commit()
’ed or drop()
’ed:
- All previous
Patch
’s get cleared - A
Patch
that simply clones all the data gets added
It is worth noting that this only happens if a mutable reference is created (even if it is not used).
§Transaction
vs Patch
Using Transaction
instead of Patch
when you are
just cloning data anyway may be preferred as it avoids:
Patch
’s allow for turning cheaply reclaimed old
Reader
data back into a viable copy, however, if your Patch
is simply cloning the data anyway, Transaction
makes more sense.
§Example
// Create `Reader/Writer` pair of a `String`.
let (reader, mut writer) = someday::new(String::new());
// Open up a transaction.
let mut tx: Transaction<'_, String> = writer.tx();
// Each one of these is silently calling `deref_mut()`
// into the target `&mut String`, which increments the
// timestamp each call, so in total, 4 times.
tx.push_str("hello");
tx.push_str(" ");
tx.push_str("world");
tx.push_str("!");
// We started with a timestamp of 0,
// and after mutating a bit, are now at 4.
assert_eq!(tx.original_timestamp(), 0);
assert_eq!(tx.current_timestamp(), 4);
// Finish the transaction by dropping,
// we don't want the `CommitInfo` data
// from `Transaction::commit()`.
drop(tx);
// We can see dropping the `Transaction` added
// a `Patch` - this just clones the data.
assert_eq!(writer.staged().len(), 1);
// Our changes were applied
// to the `Writer` data directly.
assert_eq!(writer.data(), "hello world!");
assert_eq!(writer.timestamp(), 4);
// Although, we haven't `push()`'ed yet,
// so `Reader`'s still don't see changes.
assert_eq!(reader.head().data, "");
assert_eq!(reader.head().timestamp, 0);
// `Reader`'s can see our changes after `push()`.
writer.push();
assert_eq!(reader.head().data, "hello world!");
assert_eq!(reader.head().timestamp, 4);
Implementations§
source§impl<'writer, T: Clone> Transaction<'writer, T>
impl<'writer, T: Clone> Transaction<'writer, T>
sourcepub fn new(writer: &'writer mut Writer<T>) -> Transaction<'writer, T>
pub fn new(writer: &'writer mut Writer<T>) -> Transaction<'writer, T>
Create a new Transaction
associated with a Writer
.
This is the same as Writer::tx
.
sourcepub fn writer(&self) -> &Writer<T>
pub fn writer(&self) -> &Writer<T>
Immutably borrow the Writer
’s associated with this Transaction
.
let (_, mut writer) = someday::new(String::new());
let mut tx = writer.tx();
let writer = tx.writer();
// We can access anything even while
// a `Transaction` is in-scope.
assert!(writer.data().is_empty());
// But not after it is actually being used.
tx.push_str("");
// writer.head();
sourcepub const fn original_timestamp(&self) -> Timestamp
pub const fn original_timestamp(&self) -> Timestamp
Get the original Timestamp
of when this Transaction
was created.
let (_, mut writer) = someday::new(String::new());
let mut tx = writer.tx();
tx.push_str(""); // 1
tx.push_str(""); // 2
tx.push_str(""); // 3
assert_eq!(tx.original_timestamp(), 0);
drop(tx);
assert_eq!(writer.timestamp(), 3);
let tx = writer.tx();
assert_eq!(tx.original_timestamp(), 3);
sourcepub const fn current_timestamp(&self) -> Timestamp
pub const fn current_timestamp(&self) -> Timestamp
Get the current Timestamp
of the Writer
associated with this Transaction
.
let (_, mut writer) = someday::new(String::new());
let mut tx = writer.tx();
tx.push_str(""); // 1
tx.push_str(""); // 2
tx.push_str(""); // 3
assert_eq!(tx.current_timestamp(), 3);
assert_eq!(tx.original_timestamp(), 0);
sourcepub fn commit(self) -> CommitInfo
pub fn commit(self) -> CommitInfo
Return information about the changes made
and complete the Transaction
.
This is the same as drop()
’ing the Transaction
,
except it will return a CommitInfo
.
CommitInfo::patches
in this case will represent
how many times the Transaction
was mutably referenced.
let (_, mut writer) = someday::new(String::new());
let mut tx = writer.tx();
tx.push_str(""); // 1
tx.push_str(""); // 2
tx.push_str(""); // 3
let commit_info = tx.commit();
assert_eq!(commit_info.patches, 3);
sourcepub fn abort(self) -> Result<(), Self>
pub fn abort(self) -> Result<(), Self>
Attempt to abort the Transaction
.
This cancels the Transaction
and returns Ok(())
if no mutable references to T
were created.
§Errors
If a mutable reference to T
was created with
Transaction::data_mut
, this will return self
back inside Err
.
§Example
let (_, mut writer) = someday::new(String::new());
//---------- No changes made, abort is ok
let mut tx = writer.tx();
assert!(tx.abort().is_ok());
assert_eq!(writer.data(), "");
assert_eq!(writer.timestamp(), 0);
assert_eq!(writer.staged().len(), 0);
//---------- `T` was mutated, abort fails
let mut tx = writer.tx();
tx.push_str("");
assert!(tx.abort().is_err());
//---------- Mutable reference was created, abort fails
let mut tx = writer.tx();
tx.data_mut();
assert!(tx.abort().is_err());
Trait Implementations§
source§impl<T: Clone> AsMut<T> for Transaction<'_, T>
impl<T: Clone> AsMut<T> for Transaction<'_, T>
source§impl<T: Clone> AsRef<T> for Transaction<'_, T>
impl<T: Clone> AsRef<T> for Transaction<'_, T>
source§impl<T: Clone> Borrow<T> for Transaction<'_, T>
impl<T: Clone> Borrow<T> for Transaction<'_, T>
source§impl<T: Clone> BorrowMut<T> for Transaction<'_, T>
impl<T: Clone> BorrowMut<T> for Transaction<'_, T>
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T: Clone> Deref for Transaction<'_, T>
impl<T: Clone> Deref for Transaction<'_, T>
source§impl<T: Clone> DerefMut for Transaction<'_, T>
impl<T: Clone> DerefMut for Transaction<'_, T>
Auto Trait Implementations§
impl<'writer, T> !RefUnwindSafe for Transaction<'writer, T>
impl<'writer, T> Send for Transaction<'writer, T>
impl<'writer, T> !Sync for Transaction<'writer, T>
impl<'writer, T> Unpin for Transaction<'writer, T>
impl<'writer, T> !UnwindSafe for Transaction<'writer, T>
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
source§impl<T, A> DynAccess<T> for A
impl<T, A> DynAccess<T> for A
source§fn load(&self) -> DynGuard<T>
fn load(&self) -> DynGuard<T>
Access::load
.