Skip to content

TObject Interface

Yihe (William) Huang edited this page Feb 12, 2018 · 2 revisions

The TObject interface defines methods that transactional data types must implement in order to support transactional semantics. These methods are essentially callbacks registered with STO, and they will get called under the appropriate circumstances.

To understand what these callbacks are supposed to do, it's important to understand the STO commit protocol first. STO uses a commit protocol based on an OCC implementation in Silo. It mainly consists of 3 phases: the lock phase, the validation phase, and the install phase. Most of these callbacks will be invoked over the course of the commit protocol, although some of them may be invoked when the transaction is still in execution in order to enforce opacity.

STO now works with CC mechanisms other than OCC, but the 3-phase commit protocol design is preserved. However, some of the phases may contain no-ops or special operations, depending on the situation. For example, in 2PL or adaptive CC, if a lock has already been acquired for a TItem at execution time, then the lock phase will simply skip this TItem; if we use TicToc as the CC mechanism, the validation phase will execute the special TicToc read validation/rts extension procedure. We also support predicates, which are also validated in the validation phase. To avoid A-B-A problems for predicates, we upgrade predicates to monotonic optimistic versions during the lock phase.

The TObject interface, defined in sto-core/Interface.hh, is shown below:

class TObject {
public:
    virtual ~TObject() = default;

    virtual bool lock(TransItem& item, Transaction& txn) = 0;
    virtual bool check_predicate(TransItem& item, Transaction& txn, bool committing) {
        (void) item, (void) txn, (void) committing;
        return false;
    }
    virtual bool check(TransItem& item, Transaction& txn) = 0;
    virtual void install(TransItem& item, Transaction& txn) = 0;
    virtual void unlock(TransItem& item) = 0;
    virtual void cleanup(TransItem& item, bool committed) {
        (void) item, (void) committed;
    }
    virtual void print(std::ostream& w, const TransItem& item) const;
};

bool lock(TransItem& item, Transaction& txn)

The lock method is invoked during the lock phase of the commit protocol. In this phase, lock methods will be called for each TItem of each entry in the write set of a transaction. The lock method should acquire the necessary synchronization resources (e.g. mutexes, single-bit spin locks) so that subsequent writes to the object segment covered by this lock is thread-safe.

bool check(TransItem& item, Transaction& txn)

The check method is used during the validation phase of the commit protocol. The check method should invoke the appropriate routine defined by the selected CC mechanism to ensure validity of the read set item at commit time. For OCC this is a simple version comparison. For Locking-based CC, read validation is skipped if a read lock is acquired for the TItem at execution time.

bool check_predicate(TransItem& item, Transaction& txn, bool committing)

The check_predicate method is used during the validation phase of the commit protocol. Like the check method, this method checks the predicate observed during the transaction is still valid at commit time. As mentioned before, predicates need to be upgraded to OCC versions in the lock phase before this method can be invoked during the validation phase. The committing Boolean parameter indicates whether this method is invoked at commit time.

Note: a transaction is guaranteed to commit upon passing the validation phase.

void install(TransItem& item, Transaction& txn)

The install method is called during the install phase. It writes buffered updates to the underlying data structure segments to make them visible.

void cleanup(TransItem& item, bool committed)

This method may be invoked after install or if the transaction aborts. Whether the transaction has successfully committed is indicated by the committed Boolean parameter. This method is typically used by data types to rollback inserts or finalize deletes.

void unlock(TransItem& item)

This method is invoked after the install phase or if the transaction aborts. It should release the corresponding locks acquired by the lock method for the given TItem. In principle it will only be called for ITtems whose locks are still held. Note that STO doesn't have visibility of user-defined locking behavior, so it's important that the data type register locking information correctly with STO by invoking lock methods correctly or manually setting flags in the TItem (which should be considered a hack and not recommended).

Other Methods

Note that the TObject interface doesn't cover all methods that need to be implemented to have a fully functional transactional data type; it merely ensures adherence to the STO interface. One should implement all other transactional methods (e.g. transactional insert/delete for trees, transactional pop for queue, etc.) in addition to the TObject virtual methods to have a fully functional data type.