Fix engine to use name instead of reference

Signed-off-by: Lucas Fernandes de Oliveira's avatarLucas Fernandes de Oliveira <lfo14@inf.ufpr.br>
parent 9239886b
Pipeline #7776 failed with stage
in 56 seconds
......@@ -18,8 +18,11 @@
* along with blend. If not, see <http://www.gnu.org/licenses/>.
*/
import { Metric } from "../core/metric";
import { Dimension } from "../core/dimension";
export interface Query {
public metrics: string[];
public dimensions: string[];
public metrics: Metric[];
public dimensions: Dimension[];
}
......@@ -24,8 +24,6 @@ import { Engine } from "./engine";
import { Metric } from "./metric";
import { Dimension } from "./dimension";
import { View } from "./view";
import { ViewOptions } from "./view";
import { Query } from "../common/query";
import { AggregationType } from "../common/types";
describe("engine class", () => {
......@@ -41,17 +39,19 @@ describe("engine class", () => {
const met8 = new Metric({ name: "met:8", aggregation: AggregationType.COUNT });
const met9 = new Metric({ name: "met:9", aggregation: AggregationType.SUM });
const met10 = new Metric({ name: "met:10", aggregation: AggregationType.COUNT });
const met11 = new Metric({ name: "met:11", aggregation: AggregationType.COUNT });
const dim1 = new Dimension({ name: "dim:0" });
const dim2 = new Dimension({ name: "dim:1" });
const dim3 = new Dimension({ name: "dim:2" });
const dim4 = new Dimension({ name: "dim:3" });
const dim5 = new Dimension({ name: "dim:4" });
const dim6 = new Dimension({ name: "dim:5" });
const dim7 = new Dimension({ name: "dim:6" });
const dim8 = new Dimension({ name: "dim:7" });
const dim9 = new Dimension({ name: "dim:8" });
const dim10 = new Dimension({ name: "dim:9" });
const dim1 = new Dimension({ name: "dim:1" });
const dim2 = new Dimension({ name: "dim:2" });
const dim3 = new Dimension({ name: "dim:3" });
const dim4 = new Dimension({ name: "dim:4" });
const dim5 = new Dimension({ name: "dim:5" });
const dim6 = new Dimension({ name: "dim:6" });
const dim7 = new Dimension({ name: "dim:7" });
const dim8 = new Dimension({ name: "dim:8" });
const dim9 = new Dimension({ name: "dim:9" });
const dim10 = new Dimension({ name: "dim:10" });
const dim11 = new Dimension({ name: "dim:11" });
engine.addMetric(met1);
engine.addMetric(met2);
......@@ -102,7 +102,13 @@ describe("engine class", () => {
childViews: [views[7], views[8], views[9]]
}));
views.forEach((view) => engine.addView(view));
it("should be create a fill that cover the query and has 4 children", () => {
let query = {
metrics : [met1, met2, met3, met4, met5, met6, met7, met8, met9, met10]
, dimensions : [dim1, dim2, dim3, dim4, dim5, dim6, dim7, dim8, dim9, dim10]
};
let optimalView = engine.query(query);
expect(optimalView).to.be.an("object");
expect(optimalView).to.have.property("metrics");
......@@ -114,11 +120,11 @@ describe("engine class", () => {
expect(optimalView.metrics.length === 10);
expect(optimalView.dimensions.length === 10);
expect(optimalView.childViews.length === 4);
let metAux: number[] = optimalView.metrics.sort().map((item: string) => {
return Number(item.split(":")[1]);
let metAux: number[] = optimalView.metrics.sort().map((met: Metric) => {
return Number(met.name.split(":")[1]);
});
let dimAux: number[] = optimalView.dimensions.sort().map((item: string) => {
return Number(item.split(":")[1]);
let dimAux: number[] = optimalView.dimensions.sort().map((dim: Dimension) => {
return Number(dim.name.split(":")[1]);
});
for (let i: number = 1; i <= 10; ++i) {
expect(dimAux[i] === i);
......@@ -128,7 +134,7 @@ describe("engine class", () => {
it("should throw an exception, query with non-existent metric", () => {
let error: boolean = false;
try {
engine.query({metrics: ["met:11"], dimensions: ["dim:1"]});
engine.query({metrics: [met11], dimensions: [dim1]});
}
catch (e){
error = true;
......@@ -141,7 +147,7 @@ describe("engine class", () => {
it("should throw an exception, query with non-existent dimension", () => {
let error: boolean = false;
try {
engine.query({metrics: ["met:1"], dimensions: ["dim:11"]});
engine.query({metrics: [met1], dimensions: [dim11]});
}
catch (e){
error = true;
......
......@@ -21,7 +21,6 @@
import { Dimension } from "./dimension";
import { Metric } from "./metric";
import { View } from "./view";
import { AggregationType } from "../common/types";
import { Query } from "../common/query";
export class Engine {
......@@ -49,7 +48,7 @@ export class Engine {
let result = this.metrics.find(metric => metric.name === name);
if (!result) {
throw new Error('The metric named ' + name + ' was not found');
throw new Error("The metric named " + name + " was not found");
}
return result;
......@@ -64,7 +63,7 @@ export class Engine {
let result = this.dimensions.find(dimension => dimension.name === name);
if (!result) {
throw new Error('The dimension named ' + name + ' was not found');
throw new Error("The dimension named " + name + " was not found");
}
return result;
......@@ -75,7 +74,9 @@ export class Engine {
}
private selectOptimalView (q: Query) {
let objective = q.metrics.concat(q.dimensions);
let metricsName = q.metrics.map((met) => met.name);
let dimensionsName = q.dimensions.map((dim) => dim.name);
let objective = metricsName.concat(dimensionsName);
let optimalViews: View[] = [];
let activeViews = this.getViews();
......@@ -87,7 +88,9 @@ export class Engine {
// remove views from the activeViews if they don't intersect
// with the objective
activeViews = activeViews.filter((view: View) => {
let cover = view.metrics.concat(view.dimensions);
metricsName = view.metrics.map((met) => met.name);
dimensionsName = view.dimensions.map((dim) => dim.name);
let cover = metricsName.concat(dimensionsName);
let intersection = cover.filter((item: string) => {
return objective.indexOf(item) !== -1;
});
......@@ -116,12 +119,13 @@ export class Engine {
// remove metrics and dimensions corvered by the bestView from the
// objective (i.e. the object is already met for those metrics/dimensions)
objective = objective.filter((item: string) => {
let cover = bestView.dimensions.concat(bestView.metrics);
metricsName = bestView.metrics.map((met) => met.name);
dimensionsName = bestView.dimensions.map((dim) => dim.name);
let cover = dimensionsName.concat(metricsName);
return cover.indexOf(item) === -1;
});
}
if (optimalViews.length === 1) {
// if there is a single view that covers the query, we just return it
return optimalViews.pop();
......@@ -130,18 +134,10 @@ export class Engine {
// if more than one view is necessary to cover the query,
// we need to compose them into a new singular virtual view
let map = new Map();
optimalViews.forEach((view: View) => {
view.aggregationMap.forEach((value: AggregationType, key: string) => {
map.set(key, value);
});
});
let options = {
metrics: q.metrics,
dimensions: q.dimensions,
materialized: false,
aggregationMap: map,
childViews: optimalViews
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment