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 (p) return p;
if (!this.lengthIndex[path.length]) while (this.lengthIndex.length <= path.length) {
this.lengthIndex[path.length] = new Set(); 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; let wildcard = 0;
for (let i = 0; i < path.length; ++i) { for (let i = 0; i < path.length; ++i) {
const fragment = path[i]; const fragment = path[i];
if (fragment === "*") wildcard = wildcard | (1 << i); if (fragment === "*") wildcard = wildcard | (1 << i);
if (!this.fragmentIndex[i]) this.fragmentIndex[i] = {}; const fragmentIndex = this.fragmentIndex[i];
if (!this.fragmentIndex[i][fragment]) let fragmentIndexSet = fragmentIndex.get(fragment);
this.fragmentIndex[i][fragment] = new Set(); if (!fragmentIndexSet) {
fragmentIndexSet = new Set();
fragmentIndex.set(fragment, fragmentIndexSet);
}
this.fragmentIndex[i][fragment].add(path); fragmentIndexSet.add(path);
} }
if (path.wildcard == null) { if (path.wildcard == null) {
@@ -60,27 +66,26 @@ class PathSet {
} }
get(pattern) { 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 = []; const sets = [lengthIndex];
sets.push(this.lengthIndex[pattern.length]);
for (let i = 0; i < pattern.length; ++i) { 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]; 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) => { sets.sort((a, b) => a.size - b.size);
return a.size - b.size;
});
const smallestSet = sets.shift(); const smallestSet = sets.shift();
for (let path of smallestSet) { for (let path of smallestSet) {
@@ -107,7 +112,8 @@ class PathSet {
if (!groups[0].length) return res; if (!groups[0].length) return res;
for (let i = 0; i < pattern.length; ++i) { 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]; const fragment = pattern[i];
@@ -115,27 +121,22 @@ class PathSet {
const g = []; const g = [];
if (this.fragmentIndex[i][fragment]) const s = fragmentIndex.get(fragment);
g.push(this.fragmentIndex[i][fragment]); if (s) g.push(s);
if (fragment !== "*" && superset && this.fragmentIndex[i]["*"]) if (fragment !== "*" && superset && fragmentIndex.has("*"))
g.push(this.fragmentIndex[i]["*"]); g.push(fragmentIndex.get("*"));
if (!g.length) return res; if (!g.length) return res;
groups.push(g); groups.push(g);
} }
groups.sort((a, b) => { groups.sort(
return ( (a, b) =>
a.reduce((prev, cur) => { a.reduce((prev, cur) => prev + cur.size, 0) -
return prev + cur.size; b.reduce((prev, cur) => prev + cur.size, 0)
}, 0) - );
b.reduce((prev, cur) => {
return prev + cur.size;
}, 0)
);
});
const smallestGroup = groups.shift(); const smallestGroup = groups.shift();
for (const set of smallestGroup) { for (const set of smallestGroup) {
@@ -157,7 +158,6 @@ class PathSet {
if (path) res.push(path); if (path) res.push(path);
} }
} }
return res; return res;
} }
} }
+7 -7
View File
@@ -1808,12 +1808,11 @@ function processDeclarations(
const syncState = sessionContext.syncState; const syncState = sessionContext.syncState;
const root = sessionContext.deviceData.paths.add([]); const root = sessionContext.deviceData.paths.add([]);
const paths = sessionContext.deviceData.paths.find([], false, true, 99); const paths = deviceData.paths.find([], false, true, 99);
paths.sort((a, b) => { paths.sort(
if (a.wildcard === b.wildcard) return a.length - b.length; (a, b) =>
a.wildcard === b.wildcard ? a.length - b.length : a.wildcard - b.wildcard
return a.wildcard - b.wildcard; );
});
const virtualParameterDeclarations = []; const virtualParameterDeclarations = [];
@@ -1885,7 +1884,8 @@ function processDeclarations(
leafIsObject = currentAttributes.object leafIsObject = currentAttributes.object
? currentAttributes.object[1] ? currentAttributes.object[1]
: null; : null;
if (leafIsObject === 0) // Possible V8 bug causes null === 0
if (leafIsObject != null && leafIsObject === 0)
leafTimestamp = Math.max(leafTimestamp, currentAttributes.object[0]); leafTimestamp = Math.max(leafTimestamp, currentAttributes.object[0]);
} else { } else {
leafTimestamp = Math.max(leafTimestamp, currentTimestamp); leafTimestamp = Math.max(leafTimestamp, currentTimestamp);