fabric.store.db
Class ObjectDB

java.lang.Object
  extended by fabric.store.db.ObjectDB
Direct Known Subclasses:
BdbDB, MemoryDB

public abstract class ObjectDB
extends java.lang.Object

An ObjectDB encapsulates the persistent state of the Store. It is responsible for storing and retrieving objects, and also for checking permissions.

The ObjectDB interface is designed to support a two-phase commit protocol. Consequently to insert or modify an object, users must first call the prepare() method, passing in the set of objects to update. These objects will be stored, but will remain unavailable until the commit() method is called with the returned transaction identifier.

In general, implementations of ObjectDB are not thread-safe. Only TransactionManager should be interacting directly with ObjectDB implementations; it is responsible for ensuring safe use of ObjectDB.

All ObjectDB implementations should provide a constructor which takes the name of the store and opens the appropriate back-end database if it exists, or creates it if it doesn't exist.


Nested Class Summary
protected static class ObjectDB.PendingTransaction
          The data stored for a partially prepared transaction.
 
Field Summary
protected  java.lang.String name
           
protected  LongKeyMap<OidKeyHashMap<ObjectDB.PendingTransaction>> pendingByTid
           The table of partially prepared transactions.
protected  LongKeyMap<Pair<java.lang.Long,LongKeyMap<MutableInteger>>> rwLocks
           Tracks the read/write locks for each onum.
 
Constructor Summary
protected ObjectDB(java.lang.String name)
           
 
Method Summary
 void abortPrepare(long tid, NodePrincipal worker)
          Rolls back a partially prepared transaction.
 void beginTransaction(long tid, NodePrincipal worker)
          Opens a new transaction.
 void cacheGroupContainer(LongSet onums, GroupContainer container)
          Inserts the given group container into the cache for the given onums.
abstract  void close()
          Gracefully shutdown the object database.
abstract  void commit(long tid, RemoteWorker workerNode, NodePrincipal workerPrincipal, SubscriptionManager sm)
          Cause the objects prepared in transaction [tid] to be committed.
 void ensureInit()
          Ensures that the object database has been properly initialized.
abstract  boolean exists(long onum)
          Checks whether an object with the corresponding onum exists, in either prepared or committed form.
abstract  void finishPrepare(long tid, NodePrincipal worker)
           Notifies the database that the given transaction is finished preparing.
 GroupContainer getCachedGroupContainer(long onum)
          Returns the cached GroupContainer containing the given onum.
 java.lang.String getName()
          Returns the name of this store.
 int getVersion(long onum)
          Returns the version number on the object stored at a particular onum.
protected abstract  boolean isInitialized()
          Determines whether the object database has been initialized.
 boolean isPrepared(long onum, long tid)
          Determines whether an onum has an outstanding uncommitted conflicting change or read.
 boolean isWritten(long onum)
          Determine whether an onum has outstanding uncommitted changes.
abstract  long[] newOnums(int num)
           Return a set of onums that aren't currently occupied.
protected  void notifyCommittedUpdate(SubscriptionManager sm, long onum, RemoteWorker worker)
          Performs operations in response to a committed object update.
abstract  SerializedObject read(long onum)
          Return the object stored at a particular onum.
 void registerRead(long tid, NodePrincipal worker, long onum)
          Registers that a transaction has read an object.
 void registerUpdate(long tid, NodePrincipal worker, SerializedObject obj)
          Registers that a transaction has created or written to an object.
abstract  void rollback(long tid, NodePrincipal worker)
          Cause the objects prepared in transaction [tid] to be discarded.
protected abstract  void setInitialized()
          Sets a flag to indicate that the object database has been initialized.
protected  void unpin(ObjectDB.PendingTransaction tx)
          Adjusts rwLocks to account for the fact that the given transaction is about to be committed or aborted.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

name

protected final java.lang.String name

pendingByTid

protected final LongKeyMap<OidKeyHashMap<ObjectDB.PendingTransaction>> pendingByTid

The table of partially prepared transactions. Note that this does not need to be saved to stable storage, since we only need to persist transactions that are fully prepared.

Maps tids to principal oids to PendingTransactions.


rwLocks

protected final LongKeyMap<Pair<java.lang.Long,LongKeyMap<MutableInteger>>> rwLocks

Tracks the read/write locks for each onum. Maps each onum to a pair. The first component of the pair is the tid for the write-lock holder. The second component is a map from the of tids for the read-lock holders to the number of workers in the transaction that have read locks on the onum.

This should be recomputed from the set of prepared transactions when restoring from stable storage.

Constructor Detail

ObjectDB

protected ObjectDB(java.lang.String name)
Method Detail

beginTransaction

public final void beginTransaction(long tid,
                                   NodePrincipal worker)
                            throws AccessException
Opens a new transaction.

Parameters:
worker - the worker under whose authority the transaction is running.
Throws:
AccessException - if the worker has insufficient privileges.

registerRead

public final void registerRead(long tid,
                               NodePrincipal worker,
                               long onum)
Registers that a transaction has read an object.


registerUpdate

public final void registerUpdate(long tid,
                                 NodePrincipal worker,
                                 SerializedObject obj)
Registers that a transaction has created or written to an object. This update will not become visible in the store until commit() is called for the transaction.

Parameters:
tid - the identifier for the transaction.
obj - the updated object.

abortPrepare

public final void abortPrepare(long tid,
                               NodePrincipal worker)
Rolls back a partially prepared transaction. (i.e., one for which finishPrepare() has yet to be called.)


finishPrepare

public abstract void finishPrepare(long tid,
                                   NodePrincipal worker)

Notifies the database that the given transaction is finished preparing. The transaction is not considered to be prepared until this is called. After calling this method, there should not be any further calls to registerRead() or registerUpdate() for the given transaction. This method MUST be called before calling commit().

Upon receiving this call, the object database should save the prepared transaction to stable storage so that it can be recovered in case of failure.


commit

public abstract void commit(long tid,
                            RemoteWorker workerNode,
                            NodePrincipal workerPrincipal,
                            SubscriptionManager sm)
                     throws AccessException
Cause the objects prepared in transaction [tid] to be committed. The changes will hereafter be visible to read.

Parameters:
tid - the transaction id
workerNode - the remote worker that is performing the commit
workerPrincipal - the principal requesting the commit
Throws:
AccessException - if the principal differs from the caller of prepare()

rollback

public abstract void rollback(long tid,
                              NodePrincipal worker)
                       throws AccessException
Cause the objects prepared in transaction [tid] to be discarded.

Parameters:
tid - the transaction id
worker - the principal requesting the rollback
Throws:
AccessException - if the principal differs from the caller of prepare()

read

public abstract SerializedObject read(long onum)
Return the object stored at a particular onum.

Parameters:
onum - the identifier
Returns:
the object or null if no object exists at the given onum

getVersion

public int getVersion(long onum)
               throws AccessException
Returns the version number on the object stored at a particular onum.

Throws:
AccessException - if no object exists at the given onum.

getCachedGroupContainer

public final GroupContainer getCachedGroupContainer(long onum)
Returns the cached GroupContainer containing the given onum. Null is returned if no such GroupContainer exists.


cacheGroupContainer

public final void cacheGroupContainer(LongSet onums,
                                      GroupContainer container)
Inserts the given group container into the cache for the given onums.


notifyCommittedUpdate

protected final void notifyCommittedUpdate(SubscriptionManager sm,
                                           long onum,
                                           RemoteWorker worker)
Performs operations in response to a committed object update. Removes from cache the glob associated with the onum and notifies the subscription manager of the update.

Parameters:
onum - the onum of the object that was updated.
worker - the worker that performed the update.

isPrepared

public final boolean isPrepared(long onum,
                                long tid)
Determines whether an onum has an outstanding uncommitted conflicting change or read. Outstanding uncommitted changes are always considered conflicting. Outstanding uncommitted reads are considered conflicting if they are by transactions whose tid is different from the one given.

Parameters:
onum - the object number in question

isWritten

public final boolean isWritten(long onum)
Determine whether an onum has outstanding uncommitted changes.

Parameters:
onum - the object number in question
Returns:
true if the object has been changed by a transaction that hasn't been committed or rolled back.

unpin

protected final void unpin(ObjectDB.PendingTransaction tx)
Adjusts rwLocks to account for the fact that the given transaction is about to be committed or aborted.


newOnums

public abstract long[] newOnums(int num)

Return a set of onums that aren't currently occupied. The ObjectDB may return the same onum more than once from this method, althogh doing so would encourage collisions. There is no assumption of unpredictability or randomness about the returned ids.

The returned onums should be packed in the lower 48 bits. We assume that the object database is never full, and can always provide new onums

Parameters:
num - the number of onums to return
Returns:
num fresh onums

exists

public abstract boolean exists(long onum)
Checks whether an object with the corresponding onum exists, in either prepared or committed form.

Parameters:
onum - the onum of to check
Returns:
true if an object exists for onum

getName

public final java.lang.String getName()
Returns the name of this store.


close

public abstract void close()
                    throws java.io.IOException
Gracefully shutdown the object database.

Throws:
java.io.IOException

isInitialized

protected abstract boolean isInitialized()
Determines whether the object database has been initialized.


setInitialized

protected abstract void setInitialized()
Sets a flag to indicate that the object database has been initialized.


ensureInit

public final void ensureInit()
Ensures that the object database has been properly initialized. This creates, for example, the name-service map and the store's principal, if they do not already exist in the database.