Skip to content

Commit

Permalink
MONDRIAN: Fix MONDRIAN-1076, "Add CacheControl API to flush members from
Browse files Browse the repository at this point in the history
    dimension cache", by fixing CacheControl.flush(MemberSet). That method now
    flushes members and their descendants from the dimension cache, removes
    levels from the dimension cache at or below each flushed member, and also
    flushes adjoined cells.

[git-p4: depot-paths = "//open/mondrian/": change = 14968]
  • Loading branch information
julianhyde committed Feb 21, 2012
1 parent acdfab7 commit 8fae8c5
Show file tree
Hide file tree
Showing 8 changed files with 421 additions and 160 deletions.
30 changes: 26 additions & 4 deletions src/main/mondrian/rolap/CacheControlImpl.java
Expand Up @@ -10,7 +10,6 @@
package mondrian.rolap;

import mondrian.olap.*;
import mondrian.olap.CacheControl.CellRegion;
import mondrian.olap.Id.Quoting;
import mondrian.resource.MondrianResource;
import mondrian.rolap.agg.SegmentCacheManager;
Expand Down Expand Up @@ -228,7 +227,26 @@ protected void flushRegionList(List<CellRegion> cellRegionList) {
cellRegion = createUnionRegion(cellRegions);
break;
}
flush(cellRegion);
if (!containsMeasures(cellRegion)) {
for (RolapCube cube : connection.getSchema().getCubeList()) {
flush(
createCrossjoinRegion(
createMeasuresRegion(cube),
cellRegion));
}
} else {
flush(cellRegion);
}
}

private boolean containsMeasures(CellRegion cellRegion) {
final List<Dimension> dimensionList = cellRegion.getDimensionality();
for (Dimension dimension : dimensionList) {
if (dimension.isMeasures()) {
return true;
}
}
return false;
}

public void trace(String message) {
Expand Down Expand Up @@ -498,6 +516,7 @@ public void visit(MemberCellRegion region) {
Arrays.sort(
keys,
Util.SqlNullSafeComparator.instance);
//noinspection unchecked
list.add(
new SegmentColumn(
entry.getKey(),
Expand Down Expand Up @@ -1559,7 +1578,7 @@ private class DeleteMemberCommand
extends MemberSetVisitorImpl
implements MemberEditCommandPlus
{
private final MemberSetPlus set;;
private final MemberSetPlus set;
private List<CellRegion> cellRegionList;
private Callable<Boolean> callable;

Expand All @@ -1572,7 +1591,7 @@ public String toString() {
}

public void execute(final List<CellRegion> cellRegionList) {
// NOTE: use of member makes this class non-reentrant
// NOTE: use of cellRegionList makes this class non-reentrant
this.cellRegionList = cellRegionList;
set.accept(this);
this.cellRegionList = null;
Expand Down Expand Up @@ -1800,6 +1819,9 @@ public Boolean call() throws Exception {
* @param member Member
* @param parent Member's parent (generally equals member.getParentMember)
* @param cellRegionList List of cell regions to be flushed
*
* @return Callable that yields true when the member has been added to the
* cache
*/
private Callable<Boolean> addMember(
final RolapMember member,
Expand Down
41 changes: 23 additions & 18 deletions src/main/mondrian/rolap/MemberCacheHelper.java
Expand Up @@ -4,7 +4,7 @@
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2001-2002 Kana Software, Inc.
// Copyright (C) 2001-2010 Julian Hyde and others
// Copyright (C) 2001-2012 Julian Hyde and others
// Copyright (C) 2004-2005 TONBELLER AG
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
Expand Down Expand Up @@ -186,28 +186,34 @@ public boolean isMutable()

public synchronized RolapMember removeMember(Object key)
{
// Flush entries from the level-to-members map
// for member's level and all child levels.
// Important: Do this even if the member is apparently not in the cache.
RolapLevel level = ((MemberKey) key).getLevel();
if (level == null) {
level = (RolapLevel) this.rolapHierarchy.getLevels()[0];
}
for (Iterator<Map.Entry<Pair<RolapLevel, Object>, List<RolapMember>>>
iterator = mapLevelToMembers.getCache().iterator();
iterator.hasNext();)
{
Map.Entry<Pair<RolapLevel, Object>, List<RolapMember>> entry =
iterator.next();
final RolapLevel cacheLevel = entry.getKey().left;
if (cacheLevel.equals(level)
|| (cacheLevel.getHierarchy().equals(level.getHierarchy())
&& cacheLevel.getDepth() >= level.getDepth()))
{
iterator.remove();
}
}

RolapMember member = getMember(key);
if (member == null) {
// not in cache
return null;
}

// Drop member from the level-to-members map.
// Cache key is a (level, constraint) pair,
// cache value is a list of RolapMember.
// For each cache key whose level matches, remove from the list,
// regardless of the constraint.
RolapLevel level = member.getLevel();
for (Map.Entry<Pair<RolapLevel, Object>,
List<RolapMember>> entry : mapLevelToMembers.getCache())
{
if (entry.getKey().left.equals(level)) {
List<RolapMember> peers = entry.getValue();
boolean removedIt = peers.remove(member);
Util.discard(removedIt);
}
}

// Drop member from the member-to-children map, wherever it occurs as
// a parent or as a child, regardless of the constraint.
RolapMember parent = member.getParentMember();
Expand Down Expand Up @@ -250,7 +256,6 @@ public synchronized RolapMember removeMemberAndDescendants(Object key) {
// lists of children. Do need to update inferior lists of level-peers.
return null; // STUB
}

}

// End MemberCacheHelper.java
Expand Down
37 changes: 27 additions & 10 deletions src/main/mondrian/rolap/MemberKey.java
Expand Up @@ -4,7 +4,7 @@
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2002-2002 Kana Software, Inc.
// Copyright (C) 2002-2009 Julian Hyde and others
// Copyright (C) 2002-2012 Julian Hyde and others
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
Expand All @@ -24,11 +24,13 @@
class MemberKey {
private final RolapMember parent;
private final Object value;

MemberKey(RolapMember parent, Object value) {
this.parent = parent;
this.value = value;
}
// override Object

@Override
public boolean equals(Object o) {
if (!(o instanceof MemberKey)) {
return false;
Expand All @@ -37,18 +39,33 @@ public boolean equals(Object o) {
return Util.equals(this.parent, other.parent)
&& Util.equals(this.value, other.value);
}
// override Object

@Override
public int hashCode() {
if (parent == null && value == null) {
return 0;
int h = 0;
if (value != null) {
h = value.hashCode();
}
if (parent == null && value != null) {
return (value.hashCode() << 16);
if (parent != null) {
h = (h * 31) + parent.hashCode();
}
return h;
}

/**
* Returns the level of the member that this key represents.
*
* @return Member level, or null if is root member
*/
public RolapLevel getLevel() {
if (parent == null) {
return null;
}
if (parent != null && value == null) {
return (parent.hashCode() << 16);
final RolapLevel level = parent.getLevel();
if (level.isParentChild()) {
return level;
}
return (parent.hashCode() << 16) ^ value.hashCode();
return (RolapLevel) level.getChildLevel();
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/mondrian/rolap/cache/HardSmartCache.java
Expand Up @@ -3,7 +3,7 @@
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2004-2005 TONBELLER AG
// Copyright (C) 2006-2009 Julian Hyde and others
// Copyright (C) 2006-2012 Julian Hyde and others
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand All @@ -28,6 +28,10 @@ public V get(K key) {
return cache.get(key);
}

public V remove(K key) {
return cache.remove(key);
}

public void clear() {
cache.clear();
}
Expand Down
11 changes: 10 additions & 1 deletion src/main/mondrian/rolap/cache/SmartCache.java
Expand Up @@ -3,7 +3,7 @@
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2004-2005 TONBELLER AG
// Copyright (C) 2006-2009 Julian Hyde and others
// Copyright (C) 2006-2012 Julian Hyde and others
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -34,6 +34,15 @@ public interface SmartCache <K, V> extends Iterable<Map.Entry<K, V>> {

V get(K key);

/**
* Removes a key from the cache.
*
* @param key Key
*
* @return Previous value associated with the key
*/
V remove(K key);

void clear();

int size();
Expand Down
16 changes: 6 additions & 10 deletions src/main/mondrian/rolap/cache/SoftSmartCache.java
Expand Up @@ -3,7 +3,7 @@
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2004-2005 TONBELLER AG
// Copyright (C) 2006-2009 Julian Hyde
// Copyright (C) 2006-2012 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -74,9 +74,6 @@ public synchronized V put(K key, V value) {
return null;
}

/* (non-Javadoc)
* @see mondrian.rolap.cache.SmartCache#get(java.lang.Object)
*/
public synchronized V get(K key) {
CacheReference ref = cache.get(key);
if (ref == null) {
Expand All @@ -89,16 +86,15 @@ public synchronized V get(K key) {
return value;
}

/* (non-Javadoc)
* @see mondrian.rolap.cache.SmartCache#clear()
*/
public V remove(K key) {
final CacheReference ref = cache.remove(key);
return ref == null ? null : ref.get();
}

public void clear() {
cache.clear();
}

/* (non-Javadoc)
* @see mondrian.rolap.cache.SmartCache#size()
*/
public int size() {
return cache.size();
}
Expand Down

0 comments on commit 8fae8c5

Please sign in to comment.