Remove droppedTrail. Optimize operation with consumed signatures. Restore test.
It appears the feature that tracks the occurrences that have been dropped requires too much memory.
This commit is contained in:
parent
85674ef077
commit
65daa76c6b
|
|
@ -42,6 +42,10 @@ fun trailOf(): Trail = TIntHashSet()
|
|||
|
||||
fun Signature.toTrail() = TIntHashSet(this)
|
||||
|
||||
typealias SignatureIndex = TIntObjectHashMap<List<Signature>>
|
||||
|
||||
fun signatureIndexOf() = TIntObjectHashMap<MutableList<Signature>>()
|
||||
|
||||
internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
||||
private val tag: Any) : RuleMatcher
|
||||
{
|
||||
|
|
@ -69,7 +73,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
|
||||
var lastGeneration = Generation(Layer(InitialNode()))
|
||||
|
||||
val consumedSignatures = HashSet<Signature>()
|
||||
val consumedSignatures = IndexedSignatureSet()
|
||||
|
||||
abstract inner class ReteNode
|
||||
{
|
||||
|
|
@ -218,7 +222,6 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
}
|
||||
|
||||
fun forgetContains(occ: Occurrence): Boolean {
|
||||
droppedTrail.remove(occ.identity)
|
||||
// FIXME this breaks the internal invariant
|
||||
return introTrail.remove(occ.identity)
|
||||
}
|
||||
|
|
@ -253,7 +256,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
}
|
||||
|
||||
fun update(block: UpdateBlock): Boolean {
|
||||
return block.update(nodeList, introTrail, droppedTrail)
|
||||
return block.update(nodeList, introTrail)
|
||||
}
|
||||
|
||||
fun queueUpdate(block: UpdateBlock): Layer {
|
||||
|
|
@ -274,7 +277,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
|
||||
abstract fun reset()
|
||||
|
||||
abstract fun update(nodes: LoopLinkedList<ReteNode>, introTrail: Trail, droppedTrail: Trail): Boolean
|
||||
abstract fun update(nodes: LoopLinkedList<ReteNode>, introTrail: Trail): Boolean
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -289,9 +292,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
// nodesIt = onTopOf.iterate()
|
||||
}
|
||||
|
||||
override fun update(nodes: LoopLinkedList<ReteNode>, introTrail: Trail, droppedTrail: Trail): Boolean {
|
||||
if (droppedTrail.contains(occurrence.identity)) return false
|
||||
|
||||
override fun update(nodes: LoopLinkedList<ReteNode>, introTrail: Trail): Boolean {
|
||||
var found = false
|
||||
while (true) {
|
||||
val n = onTopOf.nextNode(nodesIt)
|
||||
|
|
@ -327,7 +328,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
// NOP
|
||||
}
|
||||
|
||||
override fun update(nodes: LoopLinkedList<ReteNode>, introTrail: Trail, droppedTrail: Trail): Boolean {
|
||||
override fun update(nodes: LoopLinkedList<ReteNode>, introTrail: Trail): Boolean {
|
||||
val it = nodes.iterator()
|
||||
while (it.hasNext()) {
|
||||
val n = it.next()
|
||||
|
|
@ -336,7 +337,6 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
}
|
||||
}
|
||||
introTrail.remove(occurrence.identity)
|
||||
droppedTrail.add(occurrence.identity)
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
@ -406,6 +406,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
for (layer in layers) {
|
||||
layer.runUpdate(DropBlock(occurrence))
|
||||
}
|
||||
consumedSignatures.removeAllWith(occurrence.identity)
|
||||
return nextGeneration().reset()
|
||||
}
|
||||
|
||||
|
|
@ -468,7 +469,7 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
}
|
||||
|
||||
override fun forgetConsumed(occ: Occurrence): ReteNetwork {
|
||||
consumedSignatures.removeIf({ it.contains(occ.identity) })
|
||||
consumedSignatures.removeAllWith(occ.identity)
|
||||
return this
|
||||
}
|
||||
|
||||
|
|
@ -490,6 +491,43 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
|
|||
|
||||
}
|
||||
|
||||
class IndexedSignatureSet {
|
||||
|
||||
val signatures = HashSet<Signature>()
|
||||
|
||||
val index = signatureIndexOf()
|
||||
|
||||
fun add(signature: Signature) {
|
||||
signatures.add(signature)
|
||||
for (id in signature) {
|
||||
if (!index.contains(id)) {
|
||||
index.put(id, arrayListOf())
|
||||
}
|
||||
index.get(id).add(signature)
|
||||
}
|
||||
}
|
||||
|
||||
fun remove(signature: Signature) {
|
||||
signatures.add(signature)
|
||||
for (id in signature) {
|
||||
if (index.containsKey(id)) {
|
||||
index.get(id).remove(signature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun contains(signature: Signature): Boolean = signatures.contains(signature)
|
||||
|
||||
fun removeAllWith(id: Int) {
|
||||
if (index.contains(id)) {
|
||||
for (s in index[id]) {
|
||||
signatures.remove(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple linked list with fail-safe iterator.
|
||||
|
|
|
|||
|
|
@ -293,10 +293,6 @@ class TestRuleMatcher {
|
|||
matches().size shouldBe 0 }.run {
|
||||
|
||||
expand(bara) }.apply {
|
||||
// the constraint that has been dropped remains dropped
|
||||
matches().size shouldBe 0
|
||||
|
||||
expand(occurrence("bar", "a")) }.apply {
|
||||
matches().size shouldBe 1
|
||||
|
||||
with(matches().first()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue