Proposal: Flat 'Heap' for POJOs stored in PojoCache
brian.stansberry Jun 22, 2006 7:32 PMWe talked about the concept of a flat 'heap' for storing POJOs at the end of our clustering meeting in Las Vegas -- wanted to post here both to flesh out the idea a bit and because I've found another situation that seems to call for it.
General Problem:
Let's say we have a Person POJO with 3 fields: String name, int age, Address address. Address has string fields street, city and postcode. Application calls cache.putObject("/husband", person);
Current implementation: This data gets stored internally in a Node with Fqn "/husband". The data is stored as follows -- name and age as key value pairs in the node's data map, and Address as another Node with Fqn "/husband/address". This second "address" node is stored in the "husband" node's children map under key "address".
There are 2 ugly things about this set up.
1) The fields that define a Person are spread over two separate data structures -- the Node's data map and it's children map. Not a big deal, but this gives off a bit of a strange smell.
2) The node for the Address POJO is tightly coupled to the node for the Person POJO even though the Address object has no reference at all to the Person object. This leads to all sorts of issues when there is more than one reference to the Address, since the location in which the Address' data is stored implies the continued existence of a particular instance of Person.
Proposal:
Separate the tree structure from the storage structure. Store all complex objects in a flat structure that is not meant to be externally accessed. The cache's tree structure is maintained solely as a way to allow users to organize the objects they place in the cache. If a user calls putObject("/abc", pojo), pojo is stored in the internal area -- all that is stored in node "/abc" is a pointer to the internal area.
Each unique POJO would be stored in an individual node under root "/_JBossInternal_/_HEAP_". When the cache first identifies the existence of a new POJO, it will assign it a PojoId:
public class PojoId implements Serializable { private Address creatorAddress; private java.rmi.server.UID uid; }
The combination of Address and UID is sufficient to make a globally unique identifier for that pojo.
The Fqn for any particular Pojo would be "/_JBossInternal_/_HEAP_/".
All information that describes a POJO would be stored in the node's data map. The difference from the current implementation is that for any field that points to a complex type, a key/value pair for that field would be stored in the data map, but the value would be the PojoId of the pojo referenced by the field. So, if we had a Person pojo stored under PojoId (for short) 1234 with a reference to an Address pojo stored under PojoId 9876, the data map for /_JBossInternal_/_HEAP_/1234 would have these key/value pairs:
name="Brian Stansberry"
age=40
address=<PojoId:9876>
__jboss:internal:class__=org.jboss.cache.test.Person
AopInstance=<AopInstance@fd34a7>
If this Person were placed in the cache under Fqn "/husband", all that would be stored in the "/husband" node would be an AopInstance object with a refFqn field pointing to /_JBossInternal_/_HEAP_/1234.