diff --git a/src/main/mondrian/rolap/RolapSchema.java b/src/main/mondrian/rolap/RolapSchema.java index 48c2ce0d48..04b76b8353 100644 --- a/src/main/mondrian/rolap/RolapSchema.java +++ b/src/main/mondrian/rolap/RolapSchema.java @@ -345,13 +345,6 @@ protected void finalCleanUp() { // Cleanup the segment data. flushSegments(); - // De-register our indexes of segments - for (Cube cube : getCubes()) { - MondrianServer.forConnection(internalConnection) - .getAggregationManager().cacheMgr.getIndexRegistry() - .clearIndex(((RolapCube)cube).getStar()); - } - // Cleanup the agg JDBC cache flushJdbcSchema(); } diff --git a/src/main/mondrian/rolap/agg/SegmentCacheManager.java b/src/main/mondrian/rolap/agg/SegmentCacheManager.java index 8268b4cf30..64946bfd0a 100644 --- a/src/main/mondrian/rolap/agg/SegmentCacheManager.java +++ b/src/main/mondrian/rolap/agg/SegmentCacheManager.java @@ -24,7 +24,6 @@ import java.io.PrintWriter; import java.util.*; -import java.util.Map.Entry; import java.util.concurrent.*; /** @@ -1515,26 +1514,39 @@ public PeekResponse( /** * Registry of all the indexes that were created for this * cache manager, per {@link RolapStar}. + * + * The index is based off the checksum of the schema. */ public class SegmentCacheIndexRegistry { - private final Map indexes = - new WeakHashMap(); - /** - * Removes a star from the registry. - */ - public void clearIndex(RolapStar star) { - indexes.remove(star); - } + private final Map indexes = + Collections.synchronizedMap( + new HashMap()); /** * Returns the {@link SegmentCacheIndex} for a given * {@link RolapStar}. */ public SegmentCacheIndex getIndex(RolapStar star) { - if (!indexes.containsKey(star)) { - indexes.put(star, new SegmentCacheIndexImpl(thread)); + LOGGER.trace( + "SegmentCacheManager.SegmentCacheIndexRegistry.getIndex:" + + System.identityHashCode(star)); + + if (!indexes.containsKey(star.getSchema().getChecksum())) { + final SegmentCacheIndexImpl index = + new SegmentCacheIndexImpl(thread); + LOGGER.trace( + "SegmentCacheManager.SegmentCacheIndexRegistry.getIndex:" + + "Creating New Index " + + System.identityHashCode(index)); + indexes.put(star.getSchema().getChecksum(), index); } - return indexes.get(star); + final SegmentCacheIndex index = + indexes.get(star.getSchema().getChecksum()); + LOGGER.trace( + "SegmentCacheManager.SegmentCacheIndexRegistry.getIndex:" + + "Returning Index " + + System.identityHashCode(index)); + return index; } /** @@ -1546,21 +1558,10 @@ private SegmentCacheIndex getIndex( { // First we check the indexes that already exist. // This is fast. - for (Entry entry - : indexes.entrySet()) - { - final String factTableName = - entry.getKey().getFactTable().getTableName(); - final ByteString schemaChecksum = - entry.getKey().getSchema().getChecksum(); - if (!factTableName.equals(header.rolapStarFactTableName)) { - continue; - } - if (!schemaChecksum.equals(header.schemaChecksum)) { - continue; - } - return entry.getValue(); + if (indexes.containsKey(header.schemaChecksum)) { + return indexes.get(header.schemaChecksum); } + // The index doesn't exist. Let's create it. final RolapStar star = getStar(header); if (star == null) { diff --git a/src/main/mondrian/rolap/cache/SegmentCacheIndexImpl.java b/src/main/mondrian/rolap/cache/SegmentCacheIndexImpl.java index 9a34caebe5..cfa3fb54bd 100644 --- a/src/main/mondrian/rolap/cache/SegmentCacheIndexImpl.java +++ b/src/main/mondrian/rolap/cache/SegmentCacheIndexImpl.java @@ -24,6 +24,7 @@ import java.sql.Statement; import java.util.*; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; @@ -114,7 +115,9 @@ public List locate( if (LOGGER.isTraceEnabled()) { LOGGER.trace( - "SegmentCacheIndexImpl.locate:" + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ")locate:" + "\nschemaName:" + schemaName + "\nschemaChecksum:" + schemaChecksum + "\ncubeName:" + cubeName @@ -137,7 +140,10 @@ public List locate( compoundPredicates); final List headerList = bitkeyMap.get(starKey); if (headerList == null) { - LOGGER.trace("SegmentCacheIndexImpl.locate:NOMATCH"); + LOGGER.trace( + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ").locate:NOMATCH"); return Collections.emptyList(); } for (SegmentHeader header : headerList) { @@ -152,7 +158,10 @@ public List locate( } if (LOGGER.isTraceEnabled()) { final StringBuilder sb = - new StringBuilder("SegmentCacheIndexImpl.locate:MATCH"); + new StringBuilder( + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ").locate:MATCH"); for (SegmentHeader header : list) { sb.append("\n"); sb.append(header.toString()); @@ -170,7 +179,9 @@ public void add( checkThread(); LOGGER.debug( - "SegmentCacheIndexImpl.add:\n" + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ").add:\n" + header.toString()); HeaderInfo headerInfo = headerMap.get(header); @@ -229,6 +240,11 @@ public void update( { checkThread(); + LOGGER.trace( + "SegmentCacheIndexImpl.update: Updating header from:\n" + + oldHeader.toString() + + "\n\nto\n\n" + + newHeader.toString()); final HeaderInfo headerInfo = headerMap.get(oldHeader); headerMap.remove(oldHeader); headerMap.put(newHeader, headerInfo); @@ -286,21 +302,34 @@ public void loadFailed(SegmentHeader header, Throwable throwable) { public void remove(SegmentHeader header) { checkThread(); - LOGGER.debug( - "SegmentCacheIndexImpl.remove:\n" - + header.toString()); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace( + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ").remove:\n" + + header.toString(), + new Throwable("Removal.")); + } else { + LOGGER.debug( + "SegmentCacheIndexImpl.remove:\n" + + header.toString()); + } final HeaderInfo headerInfo = headerMap.get(header); if (headerInfo == null) { LOGGER.debug( - "SegmentCacheIndexImpl.remove:UNKNOWN HEADER"); + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ").remove:UNKNOWN HEADER"); return; } if (headerInfo.slot != null && !headerInfo.slot.isDone()) { // Cannot remove while load is pending; flag for removal after load headerInfo.removeAfterLoad = true; LOGGER.debug( - "SegmentCacheIndexImpl.remove:DEFFERED"); + "SegmentCacheIndexImpl(" + + System.identityHashCode(this) + + ").remove:DEFFERED"); return; }