|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Object
|
+--java.rmi.server.RemoteObject
|
+--java.rmi.server.RemoteServer
|
+--java.rmi.server.UnicastRemoteObject
|
+--arlut.csd.ganymede.DBNameSpace
DBNameSpaces are the objects used to manage unique value
tracking in DBFields that are
unique value constrained. DBNameSpace is smart enough to
coordinate unique value allocation and management during object
editing across concurrent transactions.
In general, transactions in Ganymede are not able to affect each other
at all, save through the acquisition of exclusive editing locks on
invidivual objects, and through the atomic acquisition of values
for unique value constrained DBFields. Once a transaction allocates
a unique value using either the mark(),
unmark(),
or reserve()
methods, no other transaction can allocate that value, until the first transaction
calls the commit(),
abort(),
or rollback()
methods.
In order to perform this unique value management, DBNameSpace maintains
a private Hashtable, uniqueHash,
that associates the allocated vales in the namespace with DBNameSpaceHandle
objects which track the transaction that is manipulating the value, if any, as well
as the DBField object in the database that is checked in with that value. The
GanymedeSession query logic takes
advantage of this to do optimized, hashed look-ups of values for unique value
constrained fields to locate objects in the database rather than having to iterate
over all objects of a given type to find a particular match.
DBNameSpaces may be defined in the server's schema editor to be either case sensitive
or case insensitive. The DBNameSpace class uses the GHashtable
class to handle the representational issues in the unique value hash for this, as well as
for things like IP address representation.
| Field Summary | |
private boolean |
caseInsensitive
treat differently-cased Strings as the same for key? |
(package private) static boolean |
debug
|
private java.lang.String |
name
the name of this namespace |
private java.util.Hashtable |
saveHash
During schema editing, we keep a copy of the uniqueHash that we had when schema edited started. |
private java.util.Hashtable |
transactions
Hashtable mapping DBEditSet's currently active modifying values in this namespace
to DBNameSpaceTransaction objects. |
(package private) static int |
TRANSCOUNT
The number of simultaneous transactions in progress that we will size the transactions hash for. |
private java.util.Hashtable |
uniqueHash
Hashtable mapping values allocated (permanently, for objects checked in to the database, or temporarily, for objects being manipulated by active transactions) in this namespace to DBNameSpaceHandle objects that track
the current status of the values. |
| Fields inherited from class java.rmi.server.UnicastRemoteObject |
|
| Fields inherited from class java.rmi.server.RemoteServer |
|
| Fields inherited from class java.rmi.server.RemoteObject |
ref |
| Constructor Summary | |
DBNameSpace(java.io.DataInput in)
Create a new DBNameSpace object from a stream definition. |
|
DBNameSpace(java.lang.String name,
boolean caseInsensitive)
Constructor for new DBNameSpace for DBStore initialization. |
|
| Method Summary | |
void |
abort(arlut.csd.ganymede.DBEditSet editSet)
Method to revert an editSet's namespace modifications to its original state. |
void |
checkpoint(arlut.csd.ganymede.DBEditSet editSet,
java.lang.String name)
Method to checkpoint namespace changes made by a specific transaction so that state can be rolled back if necessary at a later time. |
void |
clearHandle(java.lang.Object value)
Publicly accessible function used to clear the given value from this namespace in a non-transactional fashion. |
void |
commit(arlut.csd.ganymede.DBEditSet editSet)
Method to put the editSet's current namespace modifications into final effect and to make any abandoned values available for other namespaces. |
boolean |
containsKey(java.lang.Object value)
Returns true if this namespace has value allocated. |
private void |
dumpNameSpace()
|
void |
emit(java.io.DataOutput out)
Write out a namespace definition to a DataOutput stream. |
void |
emitXML(arlut.csd.ganymede.XMLDumpContext xDump)
Write out an XML entity for this namespace. |
arlut.csd.ganymede.DBNameSpaceHandle |
getHandle(java.lang.Object value)
Returns the DBNameSpaceHandle associated with the value in this namespace, or null if the value is not allocated in this namespace. |
java.lang.String |
getName()
Returns the name of this namespace. |
arlut.csd.ganymede.DBNameSpaceTransaction |
getTransactionRecord(arlut.csd.ganymede.DBEditSet transaction)
This method returns the DBNameSpaceTransaction
associated with the given transaction, creating one if one was not previously
so associated. |
boolean |
isCaseInsensitive()
Returns true if case is to be disregarded in comparing entries in namespace managed fields. |
boolean |
isSchemaEditInProgress()
Returns true if this namespace has already been checked out for schema editing. |
arlut.csd.ganymede.DBField |
lookup(java.lang.Object value)
This method allows the namespace to be used as a unique valued search index. |
boolean |
mark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value,
arlut.csd.ganymede.DBField field)
This method marks a value as being used in this namespace. |
void |
popCheckpoint(arlut.csd.ganymede.DBEditSet editSet,
java.lang.String name)
Method to remove a checkpoint from this namespace's DBNameSpaceCkPoint hash. |
void |
putHandle(java.lang.Object value,
arlut.csd.ganymede.DBNameSpaceHandle handle)
Publicly accessible function used to associate the given DBNameSpaceHandle
with a value in this namespace in a non-transactional fashion. |
void |
receive(java.io.DataInput in)
Read in a namespace definition from a DataInput stream. |
private void |
remember(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
|
boolean |
reserve(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
This method reserves a value so that the given editSet is assured of being able to use this value at some point before the transaction is commited or canceled. |
boolean |
reserve(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value,
boolean onlyUnused)
This method reserves a value so that the given editSet is assured of being able to use this value at some point before the transaction is commited or canceled. |
boolean |
rollback(arlut.csd.ganymede.DBEditSet editSet,
java.lang.String name)
Method to rollback namespace changes made by a specific transaction to a checkpoint. |
void |
schemaEditAbort()
This method aborts any changes made during schema editing. |
void |
schemaEditCheckout()
This method prepares this DBNameSpace for changes to be made during schema editing. |
void |
schemaEditCommit()
This method locks in any changes made after schema editing is complete. |
boolean |
schemaEditRegister(java.lang.Object value,
arlut.csd.ganymede.DBField field)
This method links the given value to the specified field. |
boolean |
schemaEditUnregister(java.lang.Object value,
arlut.csd.ganymede.Invid objid,
short field)
This method unlinks a single item from this namespace index, if and only if the value is associated with the object and field id specified. |
void |
schemaEditUnregister(short objectType,
short fieldId)
This method unlinks all values that are associated with the specified object type and field id from this namespace. |
void |
setInsensitive(boolean b)
Turns case sensitivity on/off. |
boolean |
setName(java.lang.String newName)
Sets the name of this namespace. |
boolean |
testmark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
This method tests to see whether a value in the namespace can be marked as in use. |
boolean |
testunmark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
This method tests to see whether a value in the namespace can be marked as not in use. |
java.lang.String |
toString()
|
boolean |
unmark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
Used to mark a value as not used in the namespace. |
| Methods inherited from class java.rmi.server.UnicastRemoteObject |
clone, exportObject, exportObject, exportObject, unexportObject |
| Methods inherited from class java.rmi.server.RemoteServer |
getClientHost, getLog, setLog |
| Methods inherited from class java.rmi.server.RemoteObject |
equals, getRef, hashCode, toStub |
| Methods inherited from class java.lang.Object |
finalize, getClass, notify, notifyAll, wait, wait, wait |
| Field Detail |
static final boolean debug
static final int TRANSCOUNT
The number of simultaneous transactions in progress that we will size the transactions hash for.
private boolean caseInsensitive
treat differently-cased Strings as the same for key?
private java.lang.String name
the name of this namespace
private java.util.Hashtable uniqueHash
Hashtable mapping values allocated (permanently, for objects checked in to the database, or
temporarily, for objects being manipulated by active transactions) in this namespace to
DBNameSpaceHandle objects that track
the current status of the values.
private java.util.Hashtable saveHash
During schema editing, we keep a copy of the uniqueHash that we had when schema edited started. If fields are detached or attached to this namespace during schema editing, we will make the appropriate changes to the uniqueHash. If the schema edit is committed, uniqueHash is kept and saveHash is cleared. If the schema edit is cancelled, uniqueHash is set back to saveHash and the saveHash reference is cleared. saveHash will always be null except during schema editing.
private java.util.Hashtable transactions
Hashtable mapping DBEditSet's currently active modifying values in this namespace
to DBNameSpaceTransaction objects.
| Constructor Detail |
public DBNameSpace(java.io.DataInput in)
throws java.io.IOException,
java.rmi.RemoteException
public DBNameSpace(java.lang.String name,
boolean caseInsensitive)
throws java.rmi.RemoteException
name - Name for this name spacecaseInsensitive - If true, case is disregarded in this namespace| Method Detail |
public void receive(java.io.DataInput in)
throws java.io.IOException
java.io.IOException
public void emit(java.io.DataOutput out)
throws java.io.IOException
java.io.IOException
public void emitXML(arlut.csd.ganymede.XMLDumpContext xDump)
throws java.io.IOException
Write out an XML entity for this namespace.
java.io.IOExceptionpublic java.lang.String getName()
getName in interface NameSpaceNameSpacepublic boolean setName(java.lang.String newName)
setName in interface NameSpaceNameSpacepublic boolean isCaseInsensitive()
isCaseInsensitive in interface NameSpaceNameSpacepublic void setInsensitive(boolean b)
setInsensitive in interface NameSpaceNameSpacepublic arlut.csd.ganymede.DBNameSpaceTransaction getTransactionRecord(arlut.csd.ganymede.DBEditSet transaction)
This method returns the DBNameSpaceTransaction
associated with the given transaction, creating one if one was not previously
so associated.
This method will always return a valid DBNameSpaceTransaction record.
public boolean containsKey(java.lang.Object value)
Returns true if this namespace has value allocated.
public arlut.csd.ganymede.DBNameSpaceHandle getHandle(java.lang.Object value)
Returns the DBNameSpaceHandle associated with the value in this namespace, or null if the value is not allocated in this namespace.
public void putHandle(java.lang.Object value,
arlut.csd.ganymede.DBNameSpaceHandle handle)
Publicly accessible function used to associate the given
DBNameSpaceHandle
with a value in this namespace in a non-transactional fashion.
Used by the DBObject
receive() method and the DBJournal's JournalEntry
class' process() method to build up the namespace during server
start-up.
public void clearHandle(java.lang.Object value)
Publicly accessible function used to clear the given value from this namespace in a non-transactional fashion.
Used by DBJournal's
JournalEntry class'
process() method to rectify the namespace during server
start-up.
public arlut.csd.ganymede.DBField lookup(java.lang.Object value)
This method allows the namespace to be used as a unique valued search index.
Note that this lookup only works for precise equality lookup.. i.e., strings must be the same capitalization and the whole works.
As well, this method is really probably useful in the context of a DBReadLock, but we're not doing anything to enforce this requirement at this point.
value - The value to search for in the namespace hash.
public boolean testmark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
This method tests to see whether a value in the namespace can be marked as in use. Such a marking is done to allow an editset to have the ability to juggle values in namespace associated fields without allowing another editset to acquire a value needed if the editset transaction is aborted.
For array db fields, all elements in the array should be testmark'ed in the context of a synchronized block on the namespace before going back and marking each value (while still in the synchronized block on the * namespace).. this ensures that we won't mark several values in an array before discovering that one of the values in a DBArrayField is already taken.
editSet - The transaction testing permission to claim value.value - The unique value desired by editSet.
public boolean mark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value,
arlut.csd.ganymede.DBField field)
This method marks a value as being used in this namespace. Marked values are held in editSet's, which are free to shuffle these reserved values around during processing. The inuse and original fields in the namespace object are used during unique value searches to do direct hash lookups without getting confused by any shuffling being performed by a current thread.
value - The unique value that transaction editset is attempting to claimfield - The DBField which will take the unique value. Used to provide an index.
public boolean reserve(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
This method reserves a value so that the given editSet is assured of being able to use this value at some point before the transaction is commited or canceled. reserve() is different from mark() in that there is no field specified to be holding the value, and that when the transaction is committed or canceled, the value will be returned to the available list. During the transaction, the transaction code can mark the value at any time with assurance that they will be able to do so.
If a transaction attempts to reserve() a value that is already being held by an object in the transaction, reserve() will return true, even though a subsequent mark() attempt would fail.
value - The unique value that transaction editset is attempting to claim
public boolean reserve(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value,
boolean onlyUnused)
This method reserves a value so that the given editSet is assured of being able to use this value at some point before the transaction is commited or canceled. reserve() is different from mark() in that there is no field specified to be holding the value, and that when the transaction is committed or canceled, the value will be returned to the available list. During the transaction, the transaction code can mark the value at any time with assurance that they will be able to do so.
If onlyUsed is false and a transaction attempts to reserve() a value that is already being held by an object in the transaction, reserve() will return true, even though a subsequent mark() attempt would fail.
value - The unique value that transaction editset is attempting to claimonlyUnused - If true, reserve() will return false if the value is already
attached to a field connected to this namespace, even if in an object attached
to the editSet provided.
public boolean testunmark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
This method tests to see whether a value in the namespace can be marked as not in use. Such a marking is done to allow an editset to have the ability to juggle values in namespace associated fields without allowing another editset to acquire a value needed if the editset transaction is aborted.
For array db fields, all elements in the array should be testunmark'ed in the context of a synchronized block on the namespace before actually unmarking all the values. See the comments in testmark() for the logic here. Note that testunmark() is less useful than testmark() because we really aren't expecting anything to prevent us from unmarking() something.
editSet - The transaction that is determining whether value can be freed.value - The unique value being tested.
public boolean unmark(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
Used to mark a value as not used in the namespace. Unmarked values are not available for other threads / editset's until commit is called on this namespace on behalf of this editset.
editSet - The transaction that is freeing value.value - The unique value being tentatively marked as unused.
public void checkpoint(arlut.csd.ganymede.DBEditSet editSet,
java.lang.String name)
Method to checkpoint namespace changes made by a specific transaction so that state can be rolled back if necessary at a later time.
editSet - The transaction that needs to be checkpointed.name - The name of the checkpoint to be marked.
public void popCheckpoint(arlut.csd.ganymede.DBEditSet editSet,
java.lang.String name)
Method to remove a checkpoint from this namespace's DBNameSpaceCkPoint hash.
This method really isn't very important, because when the transaction is committed or aborted, the checkpoints hashtable will be cleared of editSet anyway.
editSet - The transaction that is requesting the checkpoint pop.name - The name of the checkpoint to be popped.
public boolean rollback(arlut.csd.ganymede.DBEditSet editSet,
java.lang.String name)
Method to rollback namespace changes made by a specific transaction to a checkpoint.
editSet - The transaction that needs to be checkpointed.name - The name of the checkpoint to be rolled back to.
public void abort(arlut.csd.ganymede.DBEditSet editSet)
Method to revert an editSet's namespace modifications to its original state. Used when a transaction is rolled back.
editSet - The transaction whose claimed values in this namespace need to be freed.public void commit(arlut.csd.ganymede.DBEditSet editSet)
Method to put the editSet's current namespace modifications into final effect and to make any abandoned values available for other namespaces.
Note that a NameSpace should really never fail here. We assume that all NameSpace management code up to this point has functioned properly.. at this point, the EditSet has already committed changes to the DBStore and to any external processes, we're just doing paperwork at this point.
editSet - The transaction being committed.
private void remember(arlut.csd.ganymede.DBEditSet editSet,
java.lang.Object value)
private void dumpNameSpace()
public java.lang.String toString()
toString in class java.rmi.server.RemoteObjectpublic void schemaEditCheckout()
This method prepares this DBNameSpace for changes to be made during schema editing. A back-up copy of the uniqueHash is made, to allow reversion in case the schema edit is aborted. Between schemaEditCheckout() and either schemaEditCommit() or schemaEditAbort(), the schemaEditRegister() and schemaEditUnregister() methods may be called to handle attaching/detaching fields to the namespace.
public boolean isSchemaEditInProgress()
Returns true if this namespace has already been checked out for schema editing.
public void schemaEditCommit()
This method locks in any changes made after schema editing is complete.
public void schemaEditAbort()
This method aborts any changes made during schema editing.
public boolean schemaEditRegister(java.lang.Object value,
arlut.csd.ganymede.DBField field)
This method links the given value to the specified field. If the value has already been allocated, schemaEditRegister will return false and the value won't be attached to the field in question.
public boolean schemaEditUnregister(java.lang.Object value,
arlut.csd.ganymede.Invid objid,
short field)
This method unlinks a single item from this namespace index, if and only if the value is associated with the object and field id specified.
public void schemaEditUnregister(short objectType,
short fieldId)
This method unlinks all values that are associated with the specified object type and field id from this namespace.
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||