|
Download a PDF version of this Article Table of contents: Dynamic Containers™: The Key To Superior Performance
Deployment Examples |
CONCLUSION: We hope that this paper has enabled you to understand a feature of Objectivity/DB that is one of its greatest strengths. What may appear initially as bump in the smooth road is really a stepping stone that enables the software engineer to solve problems more elegantly. We have shown through examples that combining traditional thinking and design methodology with Objectivity’s container architecture results in powerful and unique solutions that you may not have realized were possible. Furthermore, with the flexibility offered only by Objectivity/DB in the aspect of locking granularity versus throughput, you can customize your application in ways impossible with other ODBMs. By taking advantage of the container architecture, high throughput, storage flexibility, security and scalability are much more easily obtained when compared with other architectures. APPENDIX: Container Pools Pattern Implementation Object Creation/Deletion Abstraction: The main area where encapsulation is key is in the area of object creation and deletion. The application developer is used to having the new operator to create objects. We will prevent this by making constructors protected. The first step is to make the constructors for your persistent-capable classes protected to prevent the application developer from using them directly. Next, you write static create methods for each of these classes which create objects and return handles to them. Example: class Data_node : public Graph_node { In the example above, the application developer would call the create method and get back an ooHandle to the new persistent object. Note that the create method as implemented above delegates the responsibility of the physical placement of the object to the pool object which is of type ContainerPool. This object’s sole function is to return a useful container whenever its method pickOne() is called. The advantage of doing abstraction of the creation and deletion of these persistent objects give you three advantages:
A ContainerPool Class The pool object above is of the ContainerPool class which we will now discuss. This class is available for download from the Objectivity InfoCenter, and can be used as-is, or adapted to suit your own needs. This class is general-purpose enough to permit distribution of objects across multiple hosts, directories and databases. There is a simpler facility for managing pools of containers in a single database, which is part of the d_session class, which is also available on the InfoCenter. This particular ContainerPool class can be persistent (embedded in another persistent-capable class) or transient. Note that all containers themselves are persistent but the pool object itself can be persistent or transient. A persistent container pool does not have to be reinitialized each time a new process needs it and can be shared among multiple clients. However, if it maintains state information such as how many times a container has been requested from it, or which is the next container to be used, there could be lock contention because you need an update lock on the container pool each time you call member functions which change the state information. If multiple container pools exist which effectively “share” the same real pool of containers, this is perhaps preferable to having to share the single ContainerPool object. Each ContainerPool instance holds onto an ooVArray(ooRef(ooContObj)) and each call to pickOne() returns an ooRef to one of the container in this array. The actual rules to determine which container is returned can depend on your own pickOne() implementation. For a more intelligent distribution mechanism, you can subclass ContainerPool and add more pickOne() methods which take different kinds of arguments including objects for clustering hints to the ContainerPool. The ContainerPool class must be initialized once during its lifetime with the init() member function. This member function takes three forms.
As long as your derived class supports this interface and returns valid hostnames, pathnames and so on, you can implement the class in any number of ways. Using this form of init allows objects to be distributed across multiple hosts, as well as multiple databases. To change the distribution scheme, you only need to modify your own Dbspec-derived class.
|
Copyright © Objectivity, Inc. 2000-2007. All Rights Reserved.