Details on the PersistentObjectManager

This manager centralizes the writing and reading of objects in one place. The easisest way to use the PersistentObjectManager is to initialize it with the class names that must be stored and use the reflecive methods provided. But this is very slow. One may then use the static methods provided, that are much more efficient but need an adaptation to every particular project.

The reflective use of PersistentObjectManager

Somewhere, at the very beginning of the application, initialize() must be called on the PersistentObjectManager class (this method is static) with two Vectors of Strings. The first Vector contain the complete names of the proxy classes that are wanted to be stored, and the second one the names of the handle classes. This distinction must be made because these two kinds of objects are stored differently on disk. Instead, the defaultInit() method can be called, but it registers every type of object currently existing (all De types and all document types provided with IRF). The main problem with the reflective use of PersitentObjectManager currently is that it is very slow, about 2.5 time slower than the hard-wired one.

The standard hard-wired use of PersistentObjectManager

This usage itself has two aspects: extending the class may be enough, but modifying its code may be necessary. If, for example, a new De class is added. Then, if this class may be used as a key in the PersistentDualKeyContainer (and thus, in a DeIntern), then the PersistentObjectManager class itself must be modified, because otherwise an instance of this new De class couldn't be written. If this class is not used as a key, but may still be used in an unmodified version IndexingFeature, then the Manager class also has to be modified: the basic mechanism for IndexingFeature directly talks to PersistentObjectManager. But if this De class is associated to a new kind of IndexingFeature, then the new IF broker, as it has to be defined, can talk to an extending class of PersistentObjectManager. In general, the Manager class has to be modified by hand as new data elements will be used as index keys. If the new defined type is a document class, the Manager class has to be edited unless those new documents can only create IndexingFeatures of a new type, in which case the new brokers defined for the IndexingFeatures will talk to an extending Manager defining all classes needed (I think there is a sort of transitive closure issue in here: if the closure (the relation being "is a client of") of all elements used by the app doesn't intersect the default group, then extending the Manager can be a good solution).

Hints: while editing the Manager to make it fit one app's needs, it could be interesting to optimize it by removing all unneeded material, like De types not used, doc types, etc. Then, if the application grows and need object types that were removed, they can be brought back with a new code so that existing DBs can still be used. The only problem with that is that applications that evolved differently may not be compatible anymore, but it shouldn't be a usual case.

Also, the order of the declarations maybe important, mainly when they appear in a cascade of ifs. The more a class is used, the earlier the test for it should appear. Don't forget then that if B extends A, then an instance i of B *IS* an A, and thus i instanceof A == true, so the tests should appear from the most specialized classes to the less ones.


National Institute of Standards and Technology Home Last updated: Tuesday, 01-Aug-2000 06:34:32 MDT

Date created: Monday, 31-Jul-00
For further information contact Paul Over (over@nist.gov) with
copy to Darrin Dimmick (ddimmick@nist.gov)