Class DbObject
- Direct Known Subclasses:
BookmarkDB, DBAnnotatedObject, EquateDB, FunctionDB, FunctionTagDB, InstructionDB, PropertyMapDB, SourceArchiveDB, SymbolDB
The general contract for database objects is that there should only ever be one instance for
a specific database object at any given time. To facilitate this, instances of database objects
should be stored in a DbCache and the cache should be queried before creating
any new instances.
Database objects have keys that are used by the database record and also serves as the key for cache lookup. They are marked as invalid when a database cache is invalidated and can be revived on a refresh as long as they haven't been deleted.
-
Field Summary
Fields -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedDbObject(long key) Constructs a new DatabaseObject and adds it to the specified cache. -
Method Summary
Modifier and TypeMethodDescriptionprotected voidChecks if this object has been deleted, in which case any use of the object is not allowed.longgetKey()Get the database key for this object.booleanReturns true if this object has been deleted.final booleanisValid()Return true if the object is known to be valid at this time.protected voidkeyChanged(long newKey) Method for updating the cache if a object record key changed.protected final booleanReturns true if the object needs to be refreshed prior to further use.protected abstract booleanTells the object to refresh its state from the database using the specified record if provided.protected booleanRefreshes the object's state from the database if it is possibly stale.protected voidMarks the object as deleted.voidInvalidate this object.protected voidsetValid()Marks this object as valid.protected booleanThis method provides a cheap (lock free) way to test if an object is valid.
-
Field Details
-
key
protected long key
-
-
Constructor Details
-
DbObject
protected DbObject(long key) Constructs a new DatabaseObject and adds it to the specified cache.- Parameters:
key- database key to uniquely identify this object
-
-
Method Details
-
getKey
public long getKey()Get the database key for this object.- Returns:
- the database key for this object.
-
setDeleted
protected void setDeleted()Marks the object as deleted. -
setInvalid
public void setInvalid()Invalidate this object. This does not necessarily mean that this object can never be used again. If the object can refresh itself, it may still be usable. -
setValid
protected void setValid()Marks this object as valid. Note that this call does no checking on its own should be used very carefully and only when the caller is absolutely sure that the object is valid. Used in a special case for default symbols that have no corresponding record. -
keyChanged
protected void keyChanged(long newKey) Method for updating the cache if a object record key changed. This is a very unusual situation and should generally be avoided.- Parameters:
newKey- the new key for the associated record for this object
-
needsRefreshing
protected final boolean needsRefreshing()Returns true if the object needs to be refreshed prior to further use. An object needs to be refreshed if the cache has been invalidated since the last time the object was checked for validity. There is a special case if the object has been deleted. It certainly doesn't need to be refreshed but clients that have the object already in hand still want to be able to call its getter methods without encountering an error. The assumption is that eventually the client will be kicked so it knows it needs to re-aquire its objects.An object that has not been deleted may be marked as stale and in need of a refresh in one of two ways. The cache was invalidated or the object was specifically marked as invalid via its
setInvalid()method. A common situation where this can occur is an undo/redo operation against the underlying database. The methodsrefreshIfNeeded(),checkDeleted(),validate(Lock)andisDeleted(Lock)are methods which will force a re-validation if required.This method is final as it is intended to be a "fast" check that doesn't require a lock to see if the object is possibly in need of a refresh. We don't want any subclass to add additional checks that might require a database lock. The idea is that if the cache modification hasn't changed, then we know the object is valid. If the modification count has changed then we may or may not be valid and stronger checks are needed which will require a lock. Subclasses should override
refreshIfNeeded(),refresh(DBRecord)to do the more robust validation checking.- Returns:
- true if this object is invalid and must be re-validated, else false if object state is currently valid which may include a deleted state.
-
isValid
public final boolean isValid()Return true if the object is known to be valid at this time. Note that this is is subtly different from being the inverse ofneedsRefreshing(), specifically in the case where the object has been deleted. For a deleted object, theisValid()method will return false, but theneedsRefreshing()will also return false.- Returns:
- true if the object is known to be valid at this time.
-
refreshIfNeeded
protected boolean refreshIfNeeded()Refreshes the object's state from the database if it is possibly stale. The check to see if an object is stale is fast, so this generally is a quick call unless an undo or redo has taken place and a true refresh is required. If a refresh is performed, the object may be discovered to be deleted. This method should only be called while holding aReentrantReadWriteLock.readLock()- Returns:
- true if the object is valid, else false if deleted
-
checkDeleted
protected void checkDeleted()Checks if this object has been deleted, in which case any use of the object is not allowed. This method should be invoked before any modifications to the object are performed to ensure it still exists and is in a valid state.- Throws:
ConcurrentModificationException- if the object has been deleted from the database.
-
validate
This method provides a cheap (lock free) way to test if an object is valid. If this object is invalid and not deleted, then the lock will be used to refresh as needed. A deleted object will not be refreshed.- Parameters:
lock- the lock that will be used if the object needs to be refreshed.- Returns:
- true if object is valid or false if deleted
-
isDeleted
Returns true if this object has been deleted. Note: once an object has been deleted, it will never be "refreshed". For example, if an object is ever deleted and is resurrected via an "undo", you will have get a fresh instance of the object.- Parameters:
lock- object cache lock object- Returns:
- true if this object has been deleted.
-
refresh
Tells the object to refresh its state from the database using the specified record if provided. The record may be null and the object is generally expected to be able to retrieve its own record from the database as needed. Is is mostly passed as a parameter for efficiency to keep an object from having to look up its record when the client already has the record in hand such as when it is iterating over records.This method generally should not be called directly as it provides no recursion protection. Instead, most clients should call
refreshIfNeeded()instead which WILL provide recursion protection. If clients must call this method, they either need to provided their own recursion protection or be absolutely certain that recursive calls won't occur.- Parameters:
record- valid record associated with object's key (optional, may be null to force record lookup or other refresh technique)- Returns:
- true if the object was able to refresh itself. Return false if record is null and object was deleted. Objects that extend this class must implement a refresh method. If an object can never refresh itself, then it should always return false.
-