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 its private key, and opens the appropriate back-end database if it exists, or creates it if it doesn't exist.
Modifier and Type | Class and Description |
---|---|
protected static class |
ObjectDB.PendingTransaction
The data stored for a partially prepared transaction.
|
static class |
ObjectDB.UpdateMode |
Modifier and Type | Field and Description |
---|---|
protected java.lang.String |
name
The store's name.
|
protected ConcurrentLongKeyMap<OidKeyHashMap<ObjectDB.PendingTransaction>> |
pendingByTid
The table of partially prepared transactions.
|
protected ConcurrentLongKeyMap<fabric.store.db.ObjectLocks> |
rwLocks
Maps onums to ObjectLocks.
|
Modifier | Constructor and Description |
---|---|
protected |
ObjectDB(java.lang.String name,
java.security.PrivateKey privateKey) |
Modifier and Type | Method and Description |
---|---|
void |
abortPrepare(long tid,
Principal worker)
Rolls back a partially prepared transaction.
|
void |
beginTransaction(long tid,
Principal worker)
Opens a new transaction.
|
abstract void |
close()
Gracefully shuts down the object database.
|
abstract void |
commit(long tid,
RemoteIdentity<RemoteWorker> workerIdentity,
SubscriptionManager sm)
Causes 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,
Principal worker)
Notifies the database that the given transaction is finished preparing.
|
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)
Determines whether an onum has outstanding uncommitted changes.
|
abstract long[] |
newOnums(int num)
Returns 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.
|
void |
prepareRead(long tid,
Principal worker,
long onum,
int version,
LongKeyMap<SerializedObject> versionConflicts)
Prepares a read against the database.
|
void |
prepareUpdate(long tid,
Principal worker,
SerializedObject obj,
LongKeyMap<SerializedObject> versionConflicts,
ObjectDB.UpdateMode mode)
Prepares a create/write against the database.
|
abstract SerializedObject |
read(long onum)
Returns the object stored at a particular onum.
|
GroupContainer |
readGroup(long onum)
Returns a GroupContainer for the object stored at a particular onum.
|
abstract void |
rollback(long tid,
Principal worker)
Causes 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.
|
protected final java.lang.String name
protected final ConcurrentLongKeyMap<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.
protected final ConcurrentLongKeyMap<fabric.store.db.ObjectLocks> rwLocks
protected ObjectDB(java.lang.String name, java.security.PrivateKey privateKey)
public final void beginTransaction(long tid, Principal worker) throws AccessException
worker
- the worker under whose authority the transaction is running.AccessException
- if the worker has insufficient privileges.public final void prepareRead(long tid, Principal worker, long onum, int version, LongKeyMap<SerializedObject> versionConflicts) throws TransactionPrepareFailedException
tid
- the identifier for the transaction preparing the read.worker
- the worker preparing the read.onum
- the object number that was read.version
- the version that was read.versionConflicts
- a map containing the transaction's version-conflict information.
If the object read was out of date, then a new entry will be added
to this map, binding the object's onum to its current version.TransactionPrepareFailedException
public final void prepareUpdate(long tid, Principal worker, SerializedObject obj, LongKeyMap<SerializedObject> versionConflicts, ObjectDB.UpdateMode mode) throws TransactionPrepareFailedException
tid
- the identifier for the transaction preparing the create/write.worker
- the worker preparing the create/write.obj
- the modified object.versionConflicts
- a map containing the transaction's version-conflict information.
If the object modified was out of date, then a new entry will be
added to this map, binding the object's onum to its current
version.TransactionPrepareFailedException
public final void abortPrepare(long tid, Principal worker)
public abstract void finishPrepare(long tid, Principal 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.
public abstract void commit(long tid, RemoteIdentity<RemoteWorker> workerIdentity, SubscriptionManager sm) throws AccessException
tid
- the transaction idworkerIdentity
- the remote worker that is performing the commitAccessException
- if the principal differs from the caller of prepare()public abstract void rollback(long tid, Principal worker) throws AccessException
tid
- the transaction idworker
- the principal requesting the rollbackAccessException
- if the principal differs from the caller of prepare()public abstract SerializedObject read(long onum)
onum
- the identifierpublic final GroupContainer readGroup(long onum)
public int getVersion(long onum) throws AccessException
AccessException
- if no object exists at the given onum.protected final void notifyCommittedUpdate(SubscriptionManager sm, long onum, RemoteWorker worker)
onum
- the onum of the object that was updated.worker
- the worker that performed the update.public final boolean isPrepared(long onum, long tid)
onum
- the object number in questionpublic final boolean isWritten(long onum)
onum
- the object number in questionprotected final void unpin(ObjectDB.PendingTransaction tx)
public abstract long[] newOnums(int num)
Returns 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
num
- the number of onums to returnpublic abstract boolean exists(long onum)
onum
- the onum of to checkpublic final java.lang.String getName()
public abstract void close() throws java.io.IOException
java.io.IOException
protected abstract boolean isInitialized()
protected abstract void setInitialized()
public final void ensureInit()