Avoid smearLevels inefficiency; instead, union after intersection
This commit is contained in:
parent
6f21190383
commit
00b92fdf1c
91
route.js
91
route.js
|
@ -1148,13 +1148,6 @@ function Routing(exports) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function crossedGestaltLevelOp(op) {
|
|
||||||
return function (p1, p2) {
|
|
||||||
return new GestaltLevel(op(p1.subscriptions, p2.advertisements),
|
|
||||||
op(p1.advertisements, p2.subscriptions));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var emptyLevel = new GestaltLevel(emptyMatcher, emptyMatcher);
|
var emptyLevel = new GestaltLevel(emptyMatcher, emptyMatcher);
|
||||||
var emptyMetaLevel = [];
|
var emptyMetaLevel = [];
|
||||||
|
|
||||||
|
@ -1241,9 +1234,21 @@ function Routing(exports) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
Gestalt.prototype.mapZip = function (other, lengthCombiner, f,
|
function maybePushLevel(levels, i, level) {
|
||||||
levelsTransformer1, levelsTransformer2)
|
if (!level.isEmpty()) {
|
||||||
{
|
while (levels.length < i) levels.push(emptyLevel);
|
||||||
|
levels.push(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function maybePushMetaLevel(metaLevels, i, metaLevel) {
|
||||||
|
if (metaLevel.length > 0) {
|
||||||
|
while (metaLevels.length < i) metaLevels.push(emptyMetaLevel);
|
||||||
|
metaLevels.push(metaLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gestalt.prototype.mapZip = function (other, lengthCombiner, f) {
|
||||||
var metaLevels = [];
|
var metaLevels = [];
|
||||||
var mls1 = this.metaLevels;
|
var mls1 = this.metaLevels;
|
||||||
var mls2 = other.metaLevels;
|
var mls2 = other.metaLevels;
|
||||||
|
@ -1252,22 +1257,14 @@ function Routing(exports) {
|
||||||
var levels = [];
|
var levels = [];
|
||||||
var ls1 = mls1[i] || emptyMetaLevel;
|
var ls1 = mls1[i] || emptyMetaLevel;
|
||||||
var ls2 = mls2[i] || emptyMetaLevel;
|
var ls2 = mls2[i] || emptyMetaLevel;
|
||||||
if (levelsTransformer1) ls1 = levelsTransformer1(ls1);
|
|
||||||
if (levelsTransformer2) ls2 = levelsTransformer2(ls2);
|
|
||||||
var nl = lengthCombiner(ls1.length, ls2.length);
|
var nl = lengthCombiner(ls1.length, ls2.length);
|
||||||
for (var j = 0; j < nl; j++) {
|
for (var j = 0; j < nl; j++) {
|
||||||
var p1 = ls1[j] || emptyLevel;
|
var p1 = ls1[j] || emptyLevel;
|
||||||
var p2 = ls2[j] || emptyLevel;
|
var p2 = ls2[j] || emptyLevel;
|
||||||
var p = f(p1, p2);
|
var p = f(p1, p2);
|
||||||
if (!p.isEmpty()) {
|
maybePushLevel(levels, j, p);
|
||||||
while (levels.length < j) levels.push(emptyLevel);
|
|
||||||
levels.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (levels.length > 0) {
|
|
||||||
while (metaLevels.length < i) metaLevels.push(emptyMetaLevel);
|
|
||||||
metaLevels.push(levels);
|
|
||||||
}
|
}
|
||||||
|
maybePushMetaLevel(metaLevels, i, levels);
|
||||||
}
|
}
|
||||||
return new Gestalt(metaLevels);
|
return new Gestalt(metaLevels);
|
||||||
};
|
};
|
||||||
|
@ -1289,12 +1286,10 @@ function Routing(exports) {
|
||||||
return arguments.length > 0 ? this.union1(gestaltUnion(arguments)) : this;
|
return arguments.length > 0 ? this.union1(gestaltUnion(arguments)) : this;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns ls, with one level dropped, and with the remaining
|
// Accumulates matchers from higher-numbered levels into
|
||||||
// matchers "smeared" across lower levels. This could end up being
|
// lower-numbered levels.
|
||||||
// reasonably expensive - possibly cache it?
|
function telescopeLevels(levels) {
|
||||||
function smearLevels(levels) {
|
|
||||||
var result = shallowCopyArray(levels);
|
var result = shallowCopyArray(levels);
|
||||||
if (result.length > 0) result.shift();
|
|
||||||
for (var i = result.length - 2; i >= 0; i--) {
|
for (var i = result.length - 2; i >= 0; i--) {
|
||||||
result[i] =
|
result[i] =
|
||||||
new GestaltLevel(union(result[i].subscriptions, result[i+1].subscriptions),
|
new GestaltLevel(union(result[i].subscriptions, result[i+1].subscriptions),
|
||||||
|
@ -1303,10 +1298,38 @@ function Routing(exports) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Gestalt.prototype.telescoped = function () {
|
||||||
|
var mls = [];
|
||||||
|
for (var i = 0; i < this.metaLevels.length; i++) {
|
||||||
|
mls.push(telescopeLevels(this.metaLevels[i]));
|
||||||
|
}
|
||||||
|
return new Gestalt(mls);
|
||||||
|
};
|
||||||
|
|
||||||
Gestalt.prototype.filter = function (perspective) {
|
Gestalt.prototype.filter = function (perspective) {
|
||||||
return this.mapZip(perspective, Math.min, crossedGestaltLevelOp(intersect),
|
var metaLevels = [];
|
||||||
null,
|
var mls1 = this.metaLevels;
|
||||||
smearLevels);
|
var mls2 = perspective.metaLevels;
|
||||||
|
var nm = Math.min(mls1.length, mls2.length);
|
||||||
|
for (var i = 0; i < nm; i++) {
|
||||||
|
var levels = [];
|
||||||
|
var ls1 = mls1[i] || emptyMetaLevel;
|
||||||
|
var ls2 = mls2[i] || emptyMetaLevel;
|
||||||
|
var nl = Math.min(ls1.length, ls2.length - 1);
|
||||||
|
for (var j = 0; j < nl; j++) {
|
||||||
|
var p1 = ls1[j] || emptyLevel;
|
||||||
|
var subs = emptyMatcher;
|
||||||
|
var advs = emptyMatcher;
|
||||||
|
for (var k = j + 1; k < ls2.length; k++) {
|
||||||
|
var p2 = ls2[k] || emptyLevel;
|
||||||
|
subs = union(subs, intersect(p1.subscriptions, p2.advertisements));
|
||||||
|
advs = union(advs, intersect(p1.advertisements, p2.subscriptions));
|
||||||
|
}
|
||||||
|
maybePushLevel(levels, j, new GestaltLevel(subs, advs));
|
||||||
|
}
|
||||||
|
maybePushMetaLevel(metaLevels, i, levels);
|
||||||
|
}
|
||||||
|
return new Gestalt(metaLevels);
|
||||||
};
|
};
|
||||||
|
|
||||||
Gestalt.prototype.match = function (perspective) {
|
Gestalt.prototype.match = function (perspective) {
|
||||||
|
@ -1314,13 +1337,15 @@ function Routing(exports) {
|
||||||
var nm = Math.min(this.metaLevels.length, perspective.metaLevels.length);
|
var nm = Math.min(this.metaLevels.length, perspective.metaLevels.length);
|
||||||
for (var i = 0; i < nm; i++) {
|
for (var i = 0; i < nm; i++) {
|
||||||
var ls1 = this.metaLevels[i] || emptyMetaLevel;
|
var ls1 = this.metaLevels[i] || emptyMetaLevel;
|
||||||
var ls2 = smearLevels(perspective.metaLevels[i] || emptyMetaLevel);
|
var ls2 = perspective.metaLevels[i] || emptyMetaLevel;
|
||||||
var nl = Math.min(ls1.length, ls2.length);
|
var nl = Math.min(ls1.length, ls2.length - 1);
|
||||||
for (var j = 0; j < nl; j++) {
|
for (var j = 0; j < nl; j++) {
|
||||||
var p1 = ls1[j] || emptyLevel;
|
var p1 = ls1[j] || emptyLevel;
|
||||||
var p2 = ls2[j] || emptyLevel;
|
for (var k = j + 1; k < ls2.length; k++) {
|
||||||
matchMatcher(p1.subscriptions, p2.advertisements, pids);
|
var p2 = ls2[k] || emptyLevel;
|
||||||
matchMatcher(p1.advertisements, p2.subscriptions, pids);
|
matchMatcher(p1.subscriptions, p2.advertisements, pids);
|
||||||
|
matchMatcher(p1.advertisements, p2.subscriptions, pids);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return setToArray(pids);
|
return setToArray(pids);
|
||||||
|
|
Loading…
Reference in New Issue