1 Reply Latest reply on May 7, 2009 5:26 PM by manik

    InternalCacheEntry storage and object design

    genman

      In storing entries to disk, I use InternalCacheEntry serialized. It would be better to have a more efficient representation, e.g. by having this class implement Externalizable. Then it'd also be good to have the default Marshaller also know how to serialize/deserialize these instances.

      Also in terms of efficiency... I do notice the Entry has a reference to a key. Not storing the key twice, e.g. A->(A,B) in the cache store would also be nice. (Why should we!?)

      Perhaps it's just bad object design here, but I don't see why having the key as part of the value makes sense... I think having a "InternalCacheValue" class AND a "InternalCacheEntry" class might be more appropriate.

      As an aside: It's also a little odd (to me) to have 4 different types of InternalCacheEntry. I would say Mortal and Immortal would be sufficient :-)

      Maybe

        • 1. Re: InternalCacheEntry storage and object design
          manik

           

          "genman" wrote:
          In storing entries to disk, I use InternalCacheEntry serialized. It would be better to have a more efficient representation, e.g. by having this class implement Externalizable. Then it'd also be good to have the default Marshaller also know how to serialize/deserialize these instances.


          The marshaller is aware of this. This is why CacheStores are initialized with the marshaller.

          "genman" wrote:

          Also in terms of efficiency... I do notice the Entry has a reference to a key. Not storing the key twice, e.g. A->(A,B) in the cache store would also be nice. (Why should we!?)


          This is needed for certain stores, where the key is not stored anywhere else (e.g., the file store where the file name is the key's hash code and the file could contain several entries).

          That said, it would penalize other uses of the InternalCacheEntry with the unnecessary field. Let me have a think about what makes sense.

          "genman" wrote:

          As an aside: It's also a little odd (to me) to have 4 different types of InternalCacheEntry. I would say Mortal and Immortal would be sufficient :-)


          This is me being pedantic about memory overhead. To support lifespans, you need 2 additional longs per entry (creation + lifespan). A single, absolute 'expiry time' cannot be calculated and stored since the API allows for overwriting lifespans (e.g., put(k, v, 1000) followed by put(k, v, 2000)). So that's the case for Mortal vs Immortal. To support maxIdle, you need 2 longs again (lastModified + maxIdle), and again these cannot be stored as a single expiry for the same reason above. And finally, TransientMortal, for the case where you set a lifespan and a maxIdle time on an entry, in which case you need 4 longs (creation, lifespan, lastModified + maxIdle). So rather than saddle all 'expirable' entries with the same 4-long overhead of TransientMortal, I prefer to break this up into separate entry types where if possible we can make do with just 2 longs, or none at all if expiry is not used.