This class is used to manage the transaction, and to log them in a file, the WAL (Write Ahead Log).

add methods

We use two methods, addRead and addWrite, to store the set of *DN*s which will be affected by a read or a write, assuming we are inside a pending transaction.

It's just a matter of storing the couple of <Dn, scope> into the current transaction.

merge methods

The merge methods (mergeExistence, mergeForwardLookup, mergeReversLookup and mergeUpdates) are just proxies on top of Transaction merge methods

wrap methods

The wrap methods construct wrappers around the target objects (Index, IndexCursor and MasterTable).

log methods

We store LogEdit instances, serialized into UserLogRecord. Here is the hierarchy for LogEdit :

When an operation is executed (a modification, we don't log anything for searches), we will store two or three records :

  • a TXN_BEGIN record, to mark the beginning of a transaction
  • an optional DataChangeContainer, which will contain all the modified index and entries
  • a TXN_COMMIT or TXN_ABORT, depending on the success or failure of the operation.

Those elements will be serialized into a UserLogRecord, following these structures (the UserLogRecord will contains either a TxnStateChange or a DataChangeContainer) :

Note that a UserLogRecord always has a type, a data length, a buffer length and an LogAnchor encapsulating the stored data.

The contained elements are :

  • (1 byte) a flag indicating that we are storing a TxnStateChange or a DataChangeContainer : either TXN or DATA
  • (int, 4 bytes) the length of the data contained into the buffer. As the buffer might be wider than the data, we keep this information around
  • (int, 4 bytes) the length of the buffer. It's always superior of the length of the data
  • a byte[], containing the serialized Transaction or DataChangeContainer
  • (3 longs, 24 bytes) the LogAnchor, a position in the log file.

All those structure will be serialized with the minimal size, so we use Externizable classes and we use readExternal() and writeExternal() directly, to save some bytes and time (this serialization is done in a locked section).

  • No labels