triePruneBranch; preparation for echo-cancellation of SCNs
This commit is contained in:
parent
d29fb17ad6
commit
e9b431c50f
|
@ -423,35 +423,38 @@ function subtract(o1, o2, subtractSuccessesOpt) {
|
|||
r2.forEach(function (val, key) { examineKey(key) });
|
||||
}
|
||||
|
||||
// Here, the target is complete. If it has only two keys,
|
||||
// one wild and one is_keyClose, and wild's continuation
|
||||
// is a $WildcardSequence and the other continuation is
|
||||
// identical to the sequence's continuation, then replace
|
||||
// the whole thing with a nested $WildcardSequence.
|
||||
// (We know w === rlookup(target, __) from before.)
|
||||
//
|
||||
// TODO: I suspect actually this applies even if there are
|
||||
// more than two keys, so long as all their continuations
|
||||
// are identical and there's at least one is_keyClose
|
||||
// alongside a wild.
|
||||
if (target.size === 2) {
|
||||
var finalW = rlookup(target, __);
|
||||
if (finalW instanceof $WildcardSequence) {
|
||||
target.forEach(function (k, key) {
|
||||
if ((key !== __) && is_keyClose(key)) {
|
||||
if (Immutable.is(k, finalW.trie)) {
|
||||
target = finalW;
|
||||
return false; // terminate the iteration early
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
return collapseWildcardSequences(target);
|
||||
}
|
||||
}
|
||||
|
||||
function collapseWildcardSequences(target) {
|
||||
// Here, the target is complete. If it has only two keys,
|
||||
// one wild and one is_keyClose, and wild's continuation
|
||||
// is a $WildcardSequence and the other continuation is
|
||||
// identical to the sequence's continuation, then replace
|
||||
// the whole thing with a nested $WildcardSequence.
|
||||
// (We know w === rlookup(target, __) from before.)
|
||||
//
|
||||
// TODO: I suspect actually this applies even if there are
|
||||
// more than two keys, so long as all their continuations
|
||||
// are identical and there's at least one is_keyClose
|
||||
// alongside a wild.
|
||||
if (target.size === 2) {
|
||||
var finalW = rlookup(target, __);
|
||||
if (finalW instanceof $WildcardSequence) {
|
||||
target.forEach(function (k, key) {
|
||||
if ((key !== __) && is_keyClose(key)) {
|
||||
if (Immutable.is(k, finalW.trie)) {
|
||||
target = finalW;
|
||||
return false; // terminate the iteration early
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
// Returns null on failed match, otherwise the appropriate success
|
||||
// value contained in the trie r.
|
||||
function matchValue(r, v) {
|
||||
|
@ -616,6 +619,20 @@ function appendTrie(m, mTailFn) {
|
|||
}
|
||||
}
|
||||
|
||||
function triePruneBranch(m, keys) {
|
||||
if (keys.isEmpty()) return emptyTrie;
|
||||
|
||||
if (is_emptyTrie(m)) return emptyTrie;
|
||||
if (m instanceof $WildcardSequence) {
|
||||
return collapseWildcardSequences(triePruneBranch(expandWildseq(m.trie), keys));
|
||||
}
|
||||
if (m instanceof $Success) return m;
|
||||
|
||||
var key = keys.first();
|
||||
var rest = keys.shift();
|
||||
return rupdate(m, key, triePruneBranch(rlookupWild(m, key), rest));
|
||||
}
|
||||
|
||||
function trieStep(m, key) {
|
||||
if (is_emptyTrie(m)) return emptyTrie;
|
||||
if (m instanceof $WildcardSequence) return (is_keyClose(key) ? m.trie : m);
|
||||
|
@ -1006,6 +1023,7 @@ module.exports.subtract = subtract;
|
|||
module.exports.matchValue = matchValue;
|
||||
module.exports.matchTrie = matchTrie;
|
||||
module.exports.appendTrie = appendTrie;
|
||||
module.exports.triePruneBranch = triePruneBranch;
|
||||
module.exports.trieStep = trieStep;
|
||||
module.exports.relabel = relabel;
|
||||
module.exports.compileProjection = compileProjection;
|
||||
|
|
|
@ -439,3 +439,53 @@ describe('intersect', function () {
|
|||
checkPrettyTrie(r.intersect(r.subtract(x, y), y), ['::: nothing']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('triePruneBranch', function () {
|
||||
it('should not affect empty trie', function () {
|
||||
checkPrettyTrie(r.triePruneBranch(r.emptyTrie, Immutable.List([])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(r.emptyTrie, Immutable.List([r.SOA])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(r.emptyTrie, Immutable.List(["x"])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(r.emptyTrie, Immutable.List([r.SOA, "x"])), ['::: nothing']);
|
||||
});
|
||||
|
||||
it('should leave a hole in a full trie', function () {
|
||||
var full = r.compilePattern(true, r.__);
|
||||
checkPrettyTrie(r.triePruneBranch(full, Immutable.List([])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(full, Immutable.List([r.SOA])),
|
||||
[' ★ >{true}',
|
||||
' <::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(full, Immutable.List(["x"])),
|
||||
[' ★ >{true}',
|
||||
' "x"::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(full, Immutable.List([r.SOA, "x"])),
|
||||
[' ★ >{true}',
|
||||
' < ★...> >{true}',
|
||||
' > >{true}',
|
||||
' "x"::: nothing']);
|
||||
});
|
||||
|
||||
it('should prune in a finite tree and leave the rest alone', function () {
|
||||
var A = r.compilePattern(true, ["y"])
|
||||
var B = r.union(r.compilePattern(true, ["x"]), A);
|
||||
var C = r.union(r.compilePattern(true, "z"), B);
|
||||
checkPrettyTrie(r.triePruneBranch(A, Immutable.List([])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(B, Immutable.List([])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(C, Immutable.List([])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(A, Immutable.List(["z"])), [' < "y" > >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(B, Immutable.List(["z"])), [' < "x" > >{true}',
|
||||
' "y" > >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(C, Immutable.List(["z"])), [' < "x" > >{true}',
|
||||
' "y" > >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(A, Immutable.List([r.SOA])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(B, Immutable.List([r.SOA])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(C, Immutable.List([r.SOA])), [' "z" >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(A, Immutable.List([r.SOA, "x"])), [' < "y" > >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(B, Immutable.List([r.SOA, "x"])), [' < "y" > >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(C, Immutable.List([r.SOA, "x"])), [' < "y" > >{true}',
|
||||
' "z" >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(A, Immutable.List([r.SOA, "y"])), ['::: nothing']);
|
||||
checkPrettyTrie(r.triePruneBranch(B, Immutable.List([r.SOA, "y"])), [' < "x" > >{true}']);
|
||||
checkPrettyTrie(r.triePruneBranch(C, Immutable.List([r.SOA, "y"])), [' < "x" > >{true}',
|
||||
' "z" >{true}']);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue