Commit da5a3c17 authored by Lucas Fernandes de Oliveira's avatar Lucas Fernandes de Oliveira

Merge branch 'issue/74' into 'develop'

Issue #74: Add topological sort to read unordered dimensions

See merge request !57
parents bc6c933f 8b1ad52c
Pipeline #15105 passed with stages
in 1 minute and 6 seconds
......@@ -26,6 +26,7 @@ import { RelationType } from "../common/types";
import { Filter } from "../core/filter";
import { Clause } from "../core/clause";
import { Source, SourceOptions} from "../core/source";
import { Tsort, TsortDep } from "./tsort";
import * as fs from "fs";
import * as yaml from "js-yaml";
......@@ -84,6 +85,10 @@ interface DimensionMap {
[key: string]: Dimension;
}
interface DimensionOptsMap {
[key: string]: DimensionStrOptions;
}
interface MetricMap {
[key: string]: Metric;
}
......@@ -140,6 +145,7 @@ export class ConfigParser {
let dimMap: DimensionMap = {};
let enumMap: EnumTypeMap = {};
let sourcMap: SourceMap = {};
let dimOptsMap: DimensionOptsMap = {};
for (let i = 0; i < metricsOpts.length; ++i) {
let met = new Metric(this.parseMetOpts(metricsOpts[i]));
......@@ -152,6 +158,30 @@ export class ConfigParser {
enumMap[enumT.name] = enumT;
}
let toSort: TsortDep[] = [];
for (let i = 0; i < dimensionsOpts.length; ++i) {
if (dimensionsOpts[i].parent) {
toSort.push({
value: dimensionsOpts[i].name,
dependOf: dimensionsOpts[i].parent
});
}
else {
toSort.push({
value: dimensionsOpts[i].name
});
}
dimOptsMap[dimensionsOpts[i].name] = dimensionsOpts[i];
}
dimensionsOpts = Tsort.dependencies(toSort).filter((name) => {
return (dimOptsMap[name]) ? true : false;
}).map((name) => {
return dimOptsMap[name];
});
for (let i = 0; i < dimensionsOpts.length; ++i) {
let dim = new Dimension(this.parseDimOpts(dimensionsOpts[i], parsed.dimensions));
parsed.dimensions.push(dim);
......
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
import { expect } from "chai";
import { Tsort, TsortDep } from "./tsort";
describe("topological sorting utility library", () => {
it("should sort the dependencies", () => {
let deps: TsortDep[] = [
{value: "dim:1", dependOf: "dim:0"},
{value: "dim:2", dependOf: "dim:0"},
{value: "dim:3", dependOf: "dim:1"},
{value: "dim:4", dependOf: "dim:2"},
{value: "dim:5", dependOf: "dim:3"},
{value: "dim:5", dependOf: "dim:2"},
];
let sorted = Tsort.dependencies(deps);
let res: string[] = ["dim:0", "dim:2", "dim:4", "dim:1", "dim:3", "dim:5"];
expect(res).to.be.a("array");
expect(res).to.not.be.empty;
for (let i = 0; i < sorted.length; ++i) {
expect(sorted[i]).to.be.a("string");
expect(sorted[i]).to.be.eql(res[i]);
}
});
});
/*
* Copyright (C) 2018 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
export interface TsortDep {
value: string;
dependOf?: string;
}
interface Graph {
[key: string]: string[];
}
interface VertexMark {
[key: string]: boolean;
}
export class Tsort {
public static dependencies(deps: TsortDep[]): string[]{
let graph: Graph = {};
let mark: VertexMark = {};
for (let i = 0; i < deps.length; ++i) {
let vertex = deps[i].dependOf;
if (!graph[deps[i].value]) {
graph[deps[i].value] = [];
mark[deps[i].value] = false;
}
if (vertex) {
if (!graph[vertex]) {
graph[vertex] = [deps[i].value];
mark[vertex] = false;
}
else {
graph[vertex].push(deps[i].value);
}
}
}
let output: string[] = [];
for (let vertex of Object.keys(graph)) {
if (!mark[vertex]) {
Tsort.markVertex(vertex, graph, mark, output);
}
}
return output;
}
private static markVertex(vertex: string, graph: Graph,
mark: VertexMark, output: string[]): void {
if (mark[vertex]) {
return;
}
mark[vertex] = true;
for (let i = 0; i < graph[vertex].length; ++i) {
Tsort.markVertex(graph[vertex][i], graph, mark, output);
}
output.unshift(vertex);
return;
}
}
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