Skip to content

Commit

Permalink
MONDRIAN: Remove Level.setApproxRowCount() (we don't want people to b…
Browse files Browse the repository at this point in the history
…e able to change the schema via the public API) and put similar functionality in SchemaReader, combining with existing method SchemaReader.getLevelCardinalityFromCache() for improved performance and consistency.

[git-p4: depot-paths = "//open/mondrian/": change = 7856]
  • Loading branch information
julianhyde committed Oct 6, 2006
1 parent bd467fe commit cc6c610
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 37 deletions.
7 changes: 5 additions & 2 deletions src/main/mondrian/olap/DelegatingSchemaReader.java
Expand Up @@ -165,8 +165,11 @@ public int getChildrenCountFromCache(Member member) {
return schemaReader.getChildrenCountFromCache(member);
}

public int getLevelCardinalityFromCache(Level level) {
return schemaReader.getLevelCardinalityFromCache(level);
public int getLevelCardinality(
Level level, boolean approximate, boolean materialize)
{
return schemaReader.getLevelCardinality(
level, approximate, materialize);
}

public Member[] getLevelMembers(Level level, Evaluator context) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/mondrian/olap/Level.java
Expand Up @@ -47,9 +47,12 @@ public interface Level extends OlapElement {
/** @return the MemberFormatter
*/
MemberFormatter getMemberFormatter();
int getApproxRowCount();

void setApproxRowCount(int length);
/**
* Returns the approximate number of members in this level, or
* {@link Integer#MIN_VALUE} if no approximation is known.
*/
int getApproxRowCount();
}

// End Level.java
8 changes: 6 additions & 2 deletions src/main/mondrian/olap/LevelBase.java
Expand Up @@ -47,8 +47,12 @@ protected LevelBase(
this.levelType = levelType;
}

public void setApproxRowCount(int length) {
approxRowCount = length;
/**
* Sets the approximate number of members in this Level.
* @see #getApproxRowCount()
*/
public void setApproxRowCount(int approxRowCount) {
this.approxRowCount = approxRowCount;
}

// from Element
Expand Down
14 changes: 10 additions & 4 deletions src/main/mondrian/olap/SchemaReader.java
Expand Up @@ -50,11 +50,17 @@ public interface SchemaReader {
int getChildrenCountFromCache(Member member);

/**
* Returns number of members in a level,
* if the information can be retrieved from cache.
* Otherwise -1 is returned
* Returns the number of members in a level, returning an approximation if
* acceptable.
*
* @param level Level
* @param approximate Whether an approximation is acceptable
* @param materialize Whether to go to disk if no approximation for the count
* is available and the members are not in cache. If false, returns
* {@link Integer#MIN_VALUE} if value is not in cache.
*/
int getLevelCardinalityFromCache(Level level);
int getLevelCardinality(
Level level, boolean approximate, boolean materialize);

/**
* Returns direct children of <code>member</code>.
Expand Down
43 changes: 36 additions & 7 deletions src/main/mondrian/rolap/RolapSchemaReader.java
Expand Up @@ -173,22 +173,51 @@ public int getChildrenCountFromCache(Member member) {
}

/**
* check, whether member reader is caching
* if yes - return level member count
* if no - return -1
* Returns number of members in a level,
* if the information can be retrieved from cache.
* Otherwise {@link Integer#MIN_VALUE}.
*/
public int getLevelCardinalityFromCache(Level level) {
private int getLevelCardinalityFromCache(Level level) {
final Hierarchy hierarchy = level.getHierarchy();
final MemberReader memberReader = getMemberReader(hierarchy);
if( !(memberReader instanceof MemberCache)) {
return -1;
return Integer.MIN_VALUE;
}
List list = ((MemberCache)memberReader).getLevelMembersFromCache((RolapLevel)level, null);
if (list == null)
return -1;
if (list == null) {
return Integer.MIN_VALUE;
}
return list.size();
}

public int getLevelCardinality(
Level level,
boolean approximate,
boolean materialize)
{
int rowCount = Integer.MIN_VALUE;
if (approximate) {
// See if the schema has an approximation.
rowCount = level.getApproxRowCount();
}

if (rowCount == Integer.MIN_VALUE) {
// See if the precise row count is available in cache.
rowCount = getLevelCardinalityFromCache(level);
}

if (rowCount == Integer.MIN_VALUE) {
if (materialize) {
// Either the approximate row count hasn't been set,
// or they want the precise row count.
rowCount = getLevelMembers(level, false).length;
// Cache it for future.
((RolapLevel) level).setApproxRowCount(rowCount);
}
}
return rowCount;
}

public Member[] getMemberChildren(Member[] members) {
return getMemberChildren(members, null);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/mondrian/xmla/RowsetDefinition.java
Expand Up @@ -3394,7 +3394,7 @@ protected void populateDimension(SchemaReader schemaReader,
*/

// Added by TWI to returned cached row numbers
int n=XmlaUtil.getCardinality(schemaReader, lastLevel);
int n=schemaReader.getLevelCardinality(lastLevel, true, true);
row.set(DimensionCardinality.name, n+1);

// TODO: I think that this is just the dimension name
Expand Down Expand Up @@ -4577,7 +4577,7 @@ protected void outputLevel(SchemaReader schemaReader,
// Get level cardinality
// According to microsoft this is:
// "The number of members in the level."
int n = XmlaUtil.getCardinality(schemaReader, level);
int n = schemaReader.getLevelCardinality(level, true, true);
row.set(LevelCardinality.name, n);

row.set(LevelType.name, getLevelType(level));
Expand Down
19 changes: 1 addition & 18 deletions src/main/mondrian/xmla/XmlaUtil.java
Expand Up @@ -11,9 +11,7 @@
*/
package mondrian.xmla;

import mondrian.olap.Level;
import mondrian.olap.MondrianException;
import mondrian.olap.SchemaReader;
import org.apache.log4j.Logger;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
Expand Down Expand Up @@ -316,29 +314,14 @@ public static String encodeBase64(byte[] bytes) {
String encodedStr = encoder.encodeBuffer(bytes);
return encodedStr;
}

public static byte[] decodeBase64(String arg) throws IOException {
// This uses Sun's private encodes, we need to find public
// implementation that can be added to Mondrian.
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
byte[] bytes = decoder.decodeBuffer(arg);
return bytes;
}

public static int getCardinality(SchemaReader schemaReader, Level level){
int approxRowCount = level.getApproxRowCount();

if (approxRowCount == Integer.MIN_VALUE)
{
// if approxRowCount == MIN_VALUE then it hasn't been set,
// need to retrieve the value.
int length = schemaReader.getLevelMembers(level, false).length;
// cache it for future
level.setApproxRowCount(length);
return length;
} else {
return approxRowCount;
}
}
}

// End XmlaUtil.java

0 comments on commit cc6c610

Please sign in to comment.