Optimize PathSet
Performance has not been tested but generally avoiding sparse arrays should result in better performance.
This commit is contained in:
1 parent
c2d55f08d4
commit
037aa9786d
2 files changed
+41
-41
No files matched your search
+34
-34
@@ -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
@@ -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);
|
||||||
|
|||||||
Reference in new issue
Block a user