[Mondrian] mondrian member cache & RolapCubeHierarchy

Will Gorman wgorman at pentaho.org
Tue Feb 5 09:11:29 EST 2008

Hi Marc,

Thanks for your questions.  See my comments below:

On Mon, 2008-02-04 at 20:27 -0800, Marc Berkowitz wrote:
> I'm working on extending the interface modrian.olap.CacheControl
> to provide some control over cached dimension membrers. I'm a bit
> puzzled by the way the cache is used by RolapCubeHierachy.
> As I understand it, there isn't a single member cache object. Instead each
> Hierarchy has its own cache; that is, each RolapHierarchy has a
> MemberReader, which can be a SmartMemberReader which has a
> MemberCacheHelper. OK.

You are right, there isn't a single member cache, instead each Hierarchy
maintains their own cache.  Shared Hierachies maintain their
cube-independent RolapMember caches, and Cube Hierarchies maintain a
cube-dependent RolapMember cache and a wrapper RolapCubeMember cache.

> But for a shared dimension, each hierarchy is a RolapCubeHierarchy, which
> "wraps" a RolapHierarchy. Actually RolapCubeHierarchy both extends and
> delegates to a RolapHierarchy, plus it contains a MemberCacheHelper of its
> own. That makes 3 independent caches: this.cacheHelper,
> delegate.cacheHelper, and rolapCubeCacheHelper.

You are right, there are three caches represented here.  I copied and
pasted the doc in RolapCubeHierarchy to help explain why there are three

 RolapCubeMember Caching Approach:

 - RolapHierarchy.SmartMemberReader.SmartCacheHelper ->
   This is the shared cache across shared hierarchies.  This member
cache only contains members loaded by non-cube specific member lookups.
This cache should only contain RolapMembers, not RolapCubeMembers
   This cache contains the RolapCubeMember objects, which are cube
specific wrappers of shared members.

 - RolapCubeHierarchy.RolapCubeHierarchyMemberReader.SmartCacheHelper ->
   This is the inherited shared cache from SmartMemberReader, and is
used when a join with the fact table is necessary,
   This cache may be redundant with rolapCubeCacheHelper.
 - A Special note regarding RolapCubeHierarchyMemberReader.cubeSource -
   This class was required for the special situation getMemberBuilder()
method call from RolapNativeSet.  This class utilizes both the
rolapCubeCacheHelper class for storing RolapCubeMembers, and also the 
   RolapCubeHierarchyMemberReader's inherited SmartCacheHelper 

> I'd have thougth a shared dimension was a single entity appearing in
> several contexts,
> and likewise all its components, so why need separate Member objects?
> If someone calls the new CacheControl to edit a member, say [Store],
> don't they want to affect
> all Cubes that use [Store]?

A shared dimension is a single entity which does appear in several
contexts.  When instantiating RolapCubeDimensions, this shared dimension
is discovered or created (see the method

We need RolapCubeMember "wrapper" objects in addition to their shared
counterparts for two reasons:

* So that the member can be cube aware
* So that cube specific selections can be computed and cached

> Even if it's correct to have a separate cache, there should be 2 not 3.
> It would be correct for RolapCubeHierarchy to construct its own
> MemberCacheHelper,
> but it should put it in the inherited field, this.cacheHelper, not in a
> new field, rolapCubeCacheHelper.

Each cache plays a role in caching members:

- The shared member cache is used for non-cube specific RolapMember
- The inherited member cache is used for cube specific RolapMember
- The cube member cache is used for cube specific RolapCubeMember
wrapper caching

These caches are not independent.  The cube member cache wraps members
from the shared and inherited member caches.

> Does any of this affect me implementing member cache control: ie do I
> have to make duplicate
> changes to 2 parallel caches?

That's a good question.  Take a look at the
which flushes the caches together, today that is the only cache control
available.  My thought would be that these three caches need to stay in
sync with one another.

I appreciate your questions, the more folks looking at this code, the
better.  Julian and I have chatted about making RolapCubeHierarchy and
RolapCubeMember interfaces vs. concrete classes, which would make it
possible to avoid the "extends and delegates" problem.


More information about the Mondrian mailing list