One goal is to provide an example BaseCollection implementation for the more serious servers to use when planning and implementing support for the mofw extension to java within their server. It supports finite memory/backingstore resources because this is a must for such servers. One reason it is programmed strictly in java is to be easy to quickly understand.
Another goal is to provide a reasonably robust and efficient persistence mechanism that can be part of Bojangles that everyone can readily use. It prereq nothing. It was written using the java File and RandomAccessFile classes for this reason.
The FilepoBC uses Unix-like file systems for persistence. These systems have an index mechanism per directory that maps names to uninterpreted byte-stream (Blob) files. Each instance of FilepoBC has a single directory whose path name is part of its EssentialData, and puts each Managed object's state in a separate file. FilepoBC provides no additional indexing mechanism. This means that FilepoBC inherits the characteristics of these file systems, including the sophistication of its directory index, its robustness (journaled metadata), its storage overhead per file, its performance characteristics, etc. Client operating systems typically provide less sophistocated techniques in their directory implementation than do server operating systems (eg, sequential vs. B-tree lookup), because they have different design points. If an instance of FilepoBC is run on a client vs. server operating system, it will have correspondingly different performance characteristics.
If the application needs different characteristics than those provided by FilepoBC, then a different BaseCollection implementation should be chosen. For example, if many small objects are needed in a BaseCollection, then a BaseCollection that wrappers a record file system or database should be chosen.
FilepoBC is an implementation of the BaseCollectionEC interface, which means that it uses an external CacheManager (the LruCacheManager) to cache its Cached objects. A single instance of LruCacheManager can cache Cache objects for multiple instances of FilepoBC or any other BaseCollectionEC.
FilepoBC is packaged as a Manageable, so that an AA can either manage it manually or assemble it into a Managed whose instances can be managed by another BaseCollection. FilepoBC is the interface name and FilepoBCImpl is the implementation class name. FilepoBC supports the optional Dependent interface because, during its activation, it needs to get its cache manager and the dependent context for its Managed objects. FilepoBC supports the optional IdentityDelegator interface because it exports references to itself as a return parameter in some of its methods.
An instance of a FilepoBCImpl can be either of the following:
FilepoBC has two objects at runtime for each activated Managed object that are instances of ManagedDel and FilepoCached. An instance of ManagedDel object is a skinny object that implements the ManagedDel interface and delegates the Manageable interface methods to a FilepoBC Cached object. To avoid having to store multiple class names for these, a FilepoBCImpl expects the AA to form these two class names by appending a managedSuffix (eg, FilepoManaged) and cachedSuffix (eg, FilepoCached) onto the interface name (eg, <package name>.Employee).
The interface name is determined as follows:
The managedSuffix and cachedSuffix are part of the EssentialData of a FilepoBC instance.
The AA prepares these two classes as follows:
FilepoBCImpl supports the createFromData() and createFromCopy() interfaces from MOFW. When the identifierKey parameter is null, these methods generate a key from a counter that is part of the FilepoBCImpl's EssentialData. The createFromDefault() is not implemented. In the future, another version of FilepoBCImpl (perhaps called FilepoBCKeyInData) that supports the createFromData() and createFromCopy() signitures with a null identifierKey parameter where the key is extracted from the EssentialData of the corresponding Managed object. We need to standardize how to tell the BaseCollection to get the key.
In all the above cases, the key is used as the file name for the Managed object.
This BC is not transactional, so it needs a way to determine how often activate Managed objects are saved to disk. There are ways available to do this:
True transactional recoverability should be implemented in the future. Because the underlying file system is not transactional, this functionality would be introduced entirely within the BC. The simplest way to do this is for the FilepoCached class to be recoverable, which means it would register with the transaction manager directly as a resource, get locks on itself on behalf of the transaction context, and participate in 2-phase commit.
For a storage subsystem that is transactional (eg, DB2, IMS, etc.), each Cached object would be a synchronization object instead of a recoverable object, which cooperates with the transaction manager to flush its cached state to the storage subsystem just prior to 2-phase commit. The storage subsystem would interact directly with the transaction manager to register as a resource and to participate in 2-phase commit.
The underlying file systems do not support query - only a list of the directory contents is provided. The current FilepoBCImpl supports only 2 query strings:
For a storage subsystem that supports query (eg, DB2), as much of the object query as possible would be mapped to a database query. This would allow the database to provide heavily filtering so that many fewer objects would need to be activated. If the object query involved data or user-defined functions in the database, then these would be mapped to the database for filtering.
For a database that is used just for persistence of objects that have new data not accessed except by the objects, the schema could be simply <identifier key>, <Blob for EssentialData >. However, if query is heavily used, the database schema may separate out from the Blob any field that needs indexing.
The exception classes introduced by FilepoBC are indicated below:
Throwable (from java) Exception (from java) MOFWReturn (from mofw) RuntimeException (from java) MOFWException (from mofw) FilepoIOException Error (from java) MOFWError (from mofw) FilepoClassNotFoundError FilepoInstantiationError FilepoIllegalAccessError FilepoClassCastToManagedDelError FilepoClassCastToFilepoCachedError FilepoClassCastToManagedError InvalidQueryError (from mofw) - evaluate FilepoCloneNotSupportedError - FilepoCommandOnIterator EDStreamFormatError (from mofw) EDStreamEndBeforeBeginError - readEnd,writeEnd EDSteamNestingLevelError - closeAfterInternalize,closeAfterExternalize EDStreamEndExpectedError - readXXX EDStreamBeginExpectedError - readXXX EDStreamClassNameError - read/writeObject,read/writeManaged EDStreamConstructorError - constructor EDStreamObjectMustBeManageableError - readObject,writeObject (will remove this one when non-Manageable objects are supported)