Skip to content

Commit

Permalink
MONDRIAN: Task 60147: Fetch multiple measures in one SQL statement;
Browse files Browse the repository at this point in the history
fixes to MonRG.

[git-p4: depot-paths = "//open/mondrian/": change = 207]
  • Loading branch information
julianhyde committed Oct 14, 2002
1 parent 4ff6d62 commit 0b3e1f0
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 92 deletions.
29 changes: 19 additions & 10 deletions src/main/mondrian/resource/ResourceGen.java
Expand Up @@ -407,16 +407,25 @@ class XmlFileTask extends ResourceGen.FileTask {
this.locale = Util.fileNameToLocale(fileName, ".xml");
}
void process(ResourceGen generator) throws IOException {
URL url = Util.convertPathToURL(getFile());
ResourceDef.ResourceBundle resourceList = Util.load(url);
generateJava(generator, resourceList, null);
if (locale != null) {
generateJava(generator, resourceList, locale);
}
if (locale == null) {
locale = Locale.getDefault();
}
generateProperties(generator, resourceList, locale);
URL url = Util.convertPathToURL(getFile());
ResourceDef.ResourceBundle resourceList = Util.load(url);
if (resourceList.locale == null) {
throw new BuildException(
"Resource file " + url + " must have locale");
}
this.locale = Util.parseLocale(resourceList.locale);
if (this.locale == null) {
throw new BuildException(
"Invalid locale " + resourceList.locale);
}
generateJava(generator, resourceList, null);
if (locale != null) {
generateJava(generator, resourceList, locale);
}
if (locale == null) {
locale = Locale.getDefault();
}
generateProperties(generator, resourceList, locale);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/mondrian/resource/Util.java
Expand Up @@ -282,7 +282,7 @@ static Locale fileNameToLocale(String fileName, String suffix) {
/**
* Parses 'localeName' into a locale.
*/
private static Locale parseLocale(String localeName) {
static Locale parseLocale(String localeName) {
int score1 = localeName.indexOf('_');
String language, country = "", variant = "";
if (score1 < 0) {
Expand Down
41 changes: 27 additions & 14 deletions src/main/mondrian/rolap/agg/Aggregation.java
Expand Up @@ -56,28 +56,35 @@
public class Aggregation
{
RolapStar star;
RolapStar.Measure measure;
RolapStar.Column[] columns;
ArrayList segments;

Aggregation(
RolapStar star, RolapStar.Measure measure, RolapStar.Column[] columns)
{
Aggregation(RolapStar star, RolapStar.Column[] columns) {
this.star = star;
this.measure = measure;
this.columns = columns;
this.segments = new ArrayList();
}

/**
* Loads a new aggregation.
* Loads a set of segments into this aggregation, one per measure,
* each constrained by the same set of column values.
*
* For example,
* measures = {unit_sales, store_sales},
* state = {CA, OR},
* gender = unconstrained
*/
void load(Object[][] constraintses, Collection pinnedSegments)
{
Segment segment = new Segment(this, constraintses);
segments.add(segment);
int pinCount = 1;
CachePool.instance().register(segment, pinCount, pinnedSegments);
void load(
RolapStar.Measure[] measures, Object[][] constraintses,
Collection pinnedSegments) {
Segment[] segments = new Segment[measures.length];
for (int i = 0; i < measures.length; i++) {
RolapStar.Measure measure = measures[i];
Segment segment = new Segment(this, measure, constraintses);
segments[i] = segment;
this.segments.add(segment);
}
Segment.load(segments, pinnedSegments);
}

/**
Expand Down Expand Up @@ -198,10 +205,13 @@ Object[][] obsolete_optimizeConstraints(Object[][] constraintses)
// return get(keys);
// }

Object get(Object[] keys)
Object get(RolapStar.Measure measure, Object[] keys)
{
for (int i = 0, count = segments.size(); i < count; i++) {
Segment segment = (Segment) segments.get(i);
if (segment.measure != measure) {
continue;
}
Object o = segment.get(keys);
if (o != null) {
// 'Util.nullValue' means right segment, but no fact table rows
Expand All @@ -219,11 +229,14 @@ Object get(Object[] keys)
* only pinned once. Returns <code>null</code> if no segment contains the
* cell.
**/
Object getAndPin(Object[] keys, Collection pinSet)
Object getAndPin(RolapStar.Measure measure, Object[] keys, Collection pinSet)
{
for (int i = 0, count = segments.size(); i < count; i++) {
Segment segment = (Segment) segments.get(i);
Object o = segment.get(keys);
if (segment.measure != measure) {
continue;
}
if (o != null) {
if (!pinSet.contains(segment)) {
CachePool.instance().pin(segment, pinSet);
Expand Down
42 changes: 28 additions & 14 deletions src/main/mondrian/rolap/agg/AggregationManager.java
Expand Up @@ -49,7 +49,7 @@ public void loadAggregations(ArrayList batches, Collection pinnedSegments) {
ArrayList requests = batch.requests;
CellRequest firstRequest = (CellRequest) requests.get(0);
RolapStar.Column[] columns = firstRequest.getColumns();
RolapStar.Measure measure = firstRequest.getMeasure();
ArrayList measuresList = new ArrayList();
HashSet[] valueSets = new HashSet[columns.length];
for (int i = 0; i < valueSets.length; i++) {
valueSets[i] = new HashSet();
Expand All @@ -63,6 +63,15 @@ public void loadAggregations(ArrayList batches, Collection pinnedSegments) {
"multi-valued key not valid in this cell request");
valueSets[j].add(value);
}
RolapStar.Measure measure = request.getMeasure();
if (!measuresList.contains(measure)) {
if (measuresList.size() > 0) {
Util.assertTrue(
measure.table.star ==
((RolapStar.Measure) measuresList.get(0)).table.star);
}
measuresList.add(measure);
}
}
Object[][] constraintses = new Object[columns.length][];
for (int j = 0; j < columns.length; j++) {
Expand All @@ -78,34 +87,37 @@ public void loadAggregations(ArrayList batches, Collection pinnedSegments) {
// todo: optimize key sets; drop a constraint if more than x% of
// the members are requested; whether we should get just the cells
// requested or expand to a n-cube
loadAggregation(measure, columns, constraintses, pinnedSegments);
RolapStar.Measure[] measures = (RolapStar.Measure[])
measuresList.toArray(
new RolapStar.Measure[measuresList.size()]);
loadAggregation(measures, columns, constraintses, pinnedSegments);
}
}

void loadAggregation(
RolapStar.Measure measure, RolapStar.Column[] columns,
RolapStar.Measure[] measures, RolapStar.Column[] columns,
Object[][] constraintses, Collection pinnedSegments)
{
RolapStar star = measure.table.star;
Aggregation aggregation = lookupAggregation(measure, columns);
RolapStar star = measures[0].table.star;
Aggregation aggregation = lookupAggregation(star, columns);
if (aggregation == null) {
aggregation = new Aggregation(star, measure, columns);
aggregation = new Aggregation(star, columns);
this.aggregations.add(aggregation);
}
constraintses = aggregation.optimizeConstraints(constraintses);
aggregation.load(constraintses, pinnedSegments);
aggregations.add(aggregation);
aggregation.load(measures, constraintses, pinnedSegments);
}

/**
* Looks for an existing aggregation over a given set of columns, or
* returns <code>null</code> if there is none.
**/
private Aggregation lookupAggregation(
RolapStar.Measure measure, RolapStar.Column[] columns)
RolapStar star, RolapStar.Column[] columns)
{
for (int i = 0, count = aggregations.size(); i < count; i++) {
Aggregation aggregation = (Aggregation) aggregations.get(i);
if (aggregation.measure == measure &&
if (aggregation.star == star &&
equals(aggregation.columns, columns)) {
return aggregation;
}
Expand All @@ -129,21 +141,23 @@ private static boolean equals(
}

public Object getCellFromCache(CellRequest request) {
RolapStar.Measure measure = request.getMeasure();
Aggregation aggregation = lookupAggregation(
request.getMeasure(), request.getColumns());
measure.table.star, request.getColumns());
if (aggregation == null) {
return null; // cell is not in any aggregation
}
return aggregation.get(request.getSingleValues());
return aggregation.get(measure, request.getSingleValues());
}

public Object getCellFromCache(CellRequest request, Set pinSet) {
RolapStar.Measure measure = request.getMeasure();
Aggregation aggregation = lookupAggregation(
request.getMeasure(), request.getColumns());
measure.table.star, request.getColumns());
if (aggregation == null) {
return null; // cell is not in any aggregation
}
return aggregation.getAndPin(request.getSingleValues(), pinSet);
return aggregation.getAndPin(measure, request.getSingleValues(), pinSet);
}

}
Expand Down
10 changes: 7 additions & 3 deletions src/main/mondrian/rolap/agg/CellRequest.java
Expand Up @@ -27,13 +27,17 @@
**/
public class CellRequest {
private RolapStar.Measure measure;
/** List of columns being which have values in this request. The 0th
* entry is a dummy entry: the star, which ensures that 2 requests for the
* same columns on measures in the same star get put into the same batch.
*/
private ArrayList columnList = new ArrayList();
private ArrayList valueList = new ArrayList();

/** Creates a {@link CellRequest}. **/
public CellRequest(RolapStar.Measure measure) {
this.measure = measure;
this.columnList.add(measure);
this.columnList.add(measure.table.star);
}

public void addConstrainedColumn(RolapStar.Column column, Object[] values) {
Expand All @@ -55,7 +59,7 @@ public RolapStar.Measure getMeasure() {
}

public RolapStar.Column[] getColumns() {
// ignore the measure, the 0th element of columnList
// ignore the star, the 0th element of columnList
RolapStar.Column[] a = new RolapStar.Column[columnList.size() - 1];
for (int i = 0; i < a.length; i++) {
a[i] = (RolapStar.Column) columnList.get(i + 1);
Expand All @@ -64,7 +68,7 @@ public RolapStar.Column[] getColumns() {
}

/** Returns a list which identifies which batch this request will
* belong to. The list contains the measure as well as the
* belong to. The list contains the star as well as the
* columns. **/
public ArrayList getBatchKey() {
return columnList;
Expand Down

0 comments on commit 0b3e1f0

Please sign in to comment.