Description
Currently most of the bindings (yrb, ypy, ywasm) only make use of TransactionMut
given single threaded nature of their environments. However TransactionMut
comes with its own cost: it initializes additional state, which upon commit must be checked through, even it transaction itself didn't made any modifications.
Aside of that we also have a WriteTxn
which is an incomplete trait over TransactionMut
: in practice we cannot really use it and instead rely on TransactionMut
directly in many places.
The proposal here is to split TransactionMut
contents into two parts:
- mut reference to Store
Option<TransactionState>
which isNone
by default.
The purpose of TransactionState
is to keep all of the data related to modifications made by transaction. Upon commit this filed can be reset to None
, making a single transaction to be able to do multiple commits. If on commit this field was already None
then we don't even need to perform all of the transaction steps.
For ergonomics, we can use WriteTxn
in order to make access-is-initialization pattern:
trait WriteTxn: ReadTxn {
/// Split transaction body into store and state. If state was not initialized,
/// initialize it and return mutable reference.
fn split_mut(&mut self) -> (&mut Store, &mut TransactionState);
/// Commit transaction. Reset its state.
fn commit(self);
}
This would require quite significant rewrite, but it would also allow us to make independent writeable transactions that could carry over some additional state like JavaScript objects etc.