Skip to content
Snippets Groups Projects
Commit d0e10959 authored by Lucas Fernandes de Oliveira's avatar Lucas Fernandes de Oliveira
Browse files

Fix engine to use name instead of reference

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