Optimize PathSet

Performance has not been tested but generally avoiding sparse arrays
should result in better performance.
This commit is contained in:
Zaid Abdulla committed 2018-09-08 23:49:14 -07:00
1 parent c2d55f08d4
commit 037aa9786d
2 files changed
+41 -41

No files matched your search

+34 -34
View File
@@ -33,22 +33,28 @@ class PathSet {
if (p) return p;
if (!this.lengthIndex[path.length])
this.lengthIndex[path.length] = new Set();
while (this.lengthIndex.length <= path.length) {
this.lengthIndex.push(new Set());
this.fragmentIndex.push(new Map());
}
this.lengthIndex[path.length].add(path);
const lengthIndex = this.lengthIndex[path.length];
lengthIndex.add(path);
let wildcard = 0;
for (let i = 0; i < path.length; ++i) {
const fragment = path[i];
if (fragment === "*") wildcard = wildcard | (1 << i);
if (!this.fragmentIndex[i]) this.fragmentIndex[i] = {};
const fragmentIndex = this.fragmentIndex[i];
if (!this.fragmentIndex[i][fragment])
this.fragmentIndex[i][fragment] = new Set();
let fragmentIndexSet = fragmentIndex.get(fragment);
if (!fragmentIndexSet) {
fragmentIndexSet = new Set();
fragmentIndex.set(fragment, fragmentIndexSet);
}
this.fragmentIndex[i][fragment].add(path);
fragmentIndexSet.add(path);
}
if (path.wildcard == null) {
@@ -60,27 +66,26 @@ class PathSet {
}
get(pattern) {
if (!this.lengthIndex[pattern.length]) return null;
const lengthIndex = this.lengthIndex[pattern.length];
if (!lengthIndex || !lengthIndex.size) return null;
if (this.lengthIndex[pattern.length].has(pattern)) return pattern;
if (lengthIndex.has(pattern)) return pattern;
const sets = [];
sets.push(this.lengthIndex[pattern.length]);
const sets = [lengthIndex];
for (let i = 0; i < pattern.length; ++i) {
if (!this.fragmentIndex[i]) return null;
const fragmentIndex = this.fragmentIndex[i];
if (!fragmentIndex || !fragmentIndex.size) return null;
const fragment = pattern[i];
if (!this.fragmentIndex[i][fragment]) return null;
const fragmentIndexSet = fragmentIndex.get(fragment);
if (!fragmentIndexSet) return null;
sets.push(this.fragmentIndex[i][fragment]);
sets.push(fragmentIndexSet);
}
sets.sort((a, b) => {
return a.size - b.size;
});
sets.sort((a, b) => a.size - b.size);
const smallestSet = sets.shift();
for (let path of smallestSet) {
@@ -107,7 +112,8 @@ class PathSet {
if (!groups[0].length) return res;
for (let i = 0; i < pattern.length; ++i) {
if (!this.fragmentIndex[i]) return res;
const fragmentIndex = this.fragmentIndex[i];
if (!fragmentIndex) return res;
const fragment = pattern[i];
@@ -115,27 +121,22 @@ class PathSet {
const g = [];
if (this.fragmentIndex[i][fragment])
g.push(this.fragmentIndex[i][fragment]);
const s = fragmentIndex.get(fragment);
if (s) g.push(s);
if (fragment !== "*" && superset && this.fragmentIndex[i]["*"])
g.push(this.fragmentIndex[i]["*"]);
if (fragment !== "*" && superset && fragmentIndex.has("*"))
g.push(fragmentIndex.get("*"));
if (!g.length) return res;
groups.push(g);
}
groups.sort((a, b) => {
return (
a.reduce((prev, cur) => {
return prev + cur.size;
}, 0) -
b.reduce((prev, cur) => {
return prev + cur.size;
}, 0)
);
});
groups.sort(
(a, b) =>
a.reduce((prev, cur) => prev + cur.size, 0) -
b.reduce((prev, cur) => prev + cur.size, 0)
);
const smallestGroup = groups.shift();
for (const set of smallestGroup) {
@@ -157,7 +158,6 @@ class PathSet {
if (path) res.push(path);
}
}
return res;
}
}