Skip to content

Commit

Permalink
improving cache management
Browse files Browse the repository at this point in the history
  • Loading branch information
gciatto committed May 23, 2020
1 parent fd0669f commit 4e1fdcd
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,8 @@ fun <T> Iterable<T>.subsequences(): Sequence<Sequence<T>> {

fun <T> subsequences(vararg items: T): Sequence<Sequence<T>> {
return sequenceOf(*items).subsequences()
}

fun <T> Sequence<T>.buffered(): Sequence<T> {
return this
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,27 @@ package it.unibo.tuprolog.collections.rete.custom
import it.unibo.tuprolog.collections.rete.custom.clause.SituatedIndexedClause

/**Marks a Class as capable of managing a cache of [SituatedIndexedClause].*/
internal interface Cacheable {
internal interface Cacheable<T> {

/**Retrieves the cache of the current level in the indexing tree*/
fun getCache(): Sequence<SituatedIndexedClause>
/** Retrieves the cache of the current level in the indexing tree */
fun getCache(): Sequence<T>

fun invalidateCache()

fun <U> invalidateCacheIfNonEmpty(seq: Sequence<U>): Sequence<U> =
sequence {
val i = seq.iterator()

if (i.hasNext()) {
invalidateCache()
yield(i.next())
}
while (i.hasNext()) {
yield(i.next())
}
}

fun <U> Sequence<U>.invalidatingCacheIfNonEmpty(): Sequence<U> =
invalidateCacheIfNonEmpty(this)

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package it.unibo.tuprolog.collections.rete.custom

import it.unibo.tuprolog.collections.rete.custom.clause.IndexedClause
import it.unibo.tuprolog.collections.rete.custom.clause.SituatedIndexedClause
import it.unibo.tuprolog.core.Clause

/**A data structure to manage the basic behaviour of the [ReteTree]*/
internal interface ReteNode : Cacheable {
internal interface ReteNode : Cacheable<SituatedIndexedClause> {

/**Reads all the clauses matching the given [Clause]*/
fun get(clause: Clause): Sequence<Clause>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package it.unibo.tuprolog.collections.rete.custom.leaf

import it.unibo.tuprolog.collections.rete.custom.IndexingLeaf

internal abstract class AbstractIndexingLeaf : IndexingLeaf {
override fun invalidateCache() {
/* do nothing */
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import it.unibo.tuprolog.utils.dequeOf
internal class AtomIndex(
private val ordered: Boolean,
private val nestingLevel: Int
) : IndexingLeaf, Retractable {
) : AbstractIndexingLeaf(), Retractable {

private val index: MutableMap<Atom, MutableList<SituatedIndexedClause>> = mutableMapOf()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,9 @@ internal class CompoundIndex(

override fun retractAll(clause: Clause): Sequence<Clause> =
if (ordered) {
retractAllOrdered(clause).let {
invalidCache(it)
it
}
retractAllOrdered(clause).invalidatingCacheIfNonEmpty()
} else {
retractAllUnordered(clause).let {
invalidCache(it)
it
}
retractAllUnordered(clause).invalidatingCacheIfNonEmpty()
}

override fun getCache(): Sequence<SituatedIndexedClause> =
Expand Down Expand Up @@ -131,18 +125,12 @@ internal class CompoundIndex(
if (clause.isGlobal()) {
Utils.merge(
functors.values.map {
it.retractAllIndexed(clause).let { res ->
invalidCache(res)
res
}
it.retractAllIndexed(clause).invalidatingCacheIfNonEmpty()
}
)
} else {
functors[clause.nestedFunctor()]
?.retractAllIndexed(clause)?.let {
invalidCache(it)
it
}
?.retractAllIndexed(clause)?.invalidatingCacheIfNonEmpty()
?: emptySequence()
}

Expand Down Expand Up @@ -170,10 +158,8 @@ internal class CompoundIndex(
private fun Clause.isGlobal(): Boolean =
this.head!!.nestedFirstArgument(nestingLevel) is Var

private fun invalidCache(result: Sequence<*>) {
if (result.any()) {
theoryCache.invalidate()
}
override fun invalidateCache() {
theoryCache.invalidate()
}

private fun regenerateCache(): MutableList<SituatedIndexedClause> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@ internal class DirectiveIndex(private val ordered: Boolean) : TopLevelReteNode {
})
}

override fun invalidateCache() {
/* do nothing */
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import it.unibo.tuprolog.utils.dequeOf
internal class NumericIndex(
private val ordered: Boolean,
private val nestingLevel: Int
) : IndexingLeaf, Retractable {
) : AbstractIndexingLeaf(), Retractable {

private val index: MutableMap<Numeric, MutableList<SituatedIndexedClause>> = mutableMapOf()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import it.unibo.tuprolog.utils.dequeOf

internal class VariableIndex(
private val ordered: Boolean
) : IndexingLeaf, Retractable {
) : AbstractIndexingLeaf(), Retractable {

private val variables: MutableList<SituatedIndexedClause> = dequeOf()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.IndexingNode
import it.unibo.tuprolog.collections.rete.custom.ReteNode

internal interface ArityIndexing : ReteNode, IndexingNode
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.*
import it.unibo.tuprolog.collections.rete.custom.IndexingLeaf
import it.unibo.tuprolog.collections.rete.custom.ReteNode
import it.unibo.tuprolog.collections.rete.custom.Retractable
import it.unibo.tuprolog.collections.rete.custom.Utils
import it.unibo.tuprolog.collections.rete.custom.Utils.nestedFirstArgument
import it.unibo.tuprolog.collections.rete.custom.clause.IndexedClause
import it.unibo.tuprolog.collections.rete.custom.clause.SituatedIndexedClause
Expand All @@ -14,10 +17,6 @@ import it.unibo.tuprolog.utils.Cached
import it.unibo.tuprolog.utils.addFirst
import it.unibo.tuprolog.utils.dequeOf

internal interface ArityRete : ReteNode, TopLevelReteNode

internal interface ArityIndexing : ReteNode, IndexingNode

internal sealed class ArityNode : ReteNode {

internal open class FamilyArityReteNode(
Expand Down Expand Up @@ -79,15 +78,9 @@ internal sealed class ArityNode : ReteNode {

override fun retractAll(clause: Clause): Sequence<Clause> =
if (ordered) {
retractAllOrdered(clause).let {
invalidCache(it)
it
}
retractAllOrdered(clause).invalidatingCacheIfNonEmpty()
} else {
retractAllUnordered(clause).let {
invalidCache(it)
it
}
retractAllUnordered(clause).invalidatingCacheIfNonEmpty()
}

override fun getCache(): Sequence<SituatedIndexedClause> =
Expand Down Expand Up @@ -267,10 +260,8 @@ internal sealed class ArityNode : ReteNode {
)
}

protected fun invalidCache(result: Sequence<*>) {
if (result.any()) {
theoryCache.invalidate()
}
override fun invalidateCache() {
theoryCache.invalidate()
}

private fun regenerateCache(): MutableList<SituatedIndexedClause> =
Expand Down Expand Up @@ -325,15 +316,9 @@ internal sealed class ArityNode : ReteNode {

override fun retractAllIndexed(clause: Clause): Sequence<SituatedIndexedClause> =
if (ordered) {
retractAllOrderedIndexed(clause).let {
invalidCache(it)
it
}
retractAllOrderedIndexed(clause).invalidatingCacheIfNonEmpty()
} else {
retractAllUnorderedIndexed(clause).let {
invalidCache(it)
it
}
retractAllUnorderedIndexed(clause).invalidatingCacheIfNonEmpty()
}

override fun extractGlobalIndexedSequence(clause: Clause): Sequence<SituatedIndexedClause> {
Expand Down Expand Up @@ -399,6 +384,10 @@ internal sealed class ArityNode : ReteNode {
return atoms.asSequence()
}

override fun invalidateCache() {
/* do nothing */
}

override fun retractIndexed(indexed: SituatedIndexedClause) {
atoms.remove(indexed)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.ReteNode
import it.unibo.tuprolog.collections.rete.custom.TopLevelReteNode

internal interface ArityRete : ReteNode, TopLevelReteNode
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.IndexingNode
import it.unibo.tuprolog.collections.rete.custom.ReteNode

internal interface FunctorIndexing : ReteNode,
IndexingNode
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.IndexingNode
import it.unibo.tuprolog.collections.rete.custom.ReteNode
import it.unibo.tuprolog.collections.rete.custom.TopLevelReteNode
import it.unibo.tuprolog.collections.rete.custom.Utils
Expand All @@ -12,12 +11,9 @@ import it.unibo.tuprolog.core.Clause
import it.unibo.tuprolog.core.Var
import it.unibo.tuprolog.unify.Unificator.Companion.matches
import it.unibo.tuprolog.utils.Cached
import it.unibo.tuprolog.utils.buffered
import it.unibo.tuprolog.utils.dequeOf

internal interface FunctorRete : ReteNode, TopLevelReteNode

internal interface FunctorIndexing : ReteNode, IndexingNode

internal sealed class FunctorNode : ReteNode {

internal class TopLevelFunctorReteNode(
Expand All @@ -40,16 +36,12 @@ internal sealed class FunctorNode : ReteNode {
}

override fun retractFirst(clause: Clause): Sequence<Clause> =
selectArity(clause)?.retractFirst(clause)?.let {
invalidCache(it)
it
} ?: emptySequence()
selectArity(clause)?.retractFirst(clause)?.invalidatingCacheIfNonEmpty()
?: emptySequence()

override fun retractAll(clause: Clause): Sequence<Clause> =
selectArity(clause)?.retractAll(clause)?.let {
invalidCache(it)
it
} ?: emptySequence()
selectArity(clause)?.retractAll(clause)?.invalidatingCacheIfNonEmpty()
?: emptySequence()

override fun getCache(): Sequence<SituatedIndexedClause> =
theoryCache.value.asSequence()
Expand All @@ -70,10 +62,8 @@ internal sealed class FunctorNode : ReteNode {
}.run { op(clause) }
}

private fun invalidCache(result: Sequence<*>) {
if (result.any()) {
theoryCache.invalidate()
}
override fun invalidateCache() {
theoryCache.invalidate()
}

private fun regenerateCache(): MutableList<SituatedIndexedClause> =
Expand Down Expand Up @@ -118,10 +108,8 @@ internal sealed class FunctorNode : ReteNode {
}

override fun retractAll(clause: Clause): Sequence<Clause> =
arities[clause.nestedArity()]?.retractAll(clause)?.let {
invalidCache(it)
it
} ?: emptySequence()
arities[clause.nestedArity()]?.retractAll(clause)?.invalidatingCacheIfNonEmpty()
?: emptySequence()

override fun getCache(): Sequence<SituatedIndexedClause> =
theoryCache.value.asSequence()
Expand Down Expand Up @@ -150,21 +138,17 @@ internal sealed class FunctorNode : ReteNode {

override fun retractAllIndexed(clause: Clause): Sequence<SituatedIndexedClause> =
if (clause.isGlobal()) {
val partialResult = Utils.merge(
Utils.merge(
arities.values.map {
it.extractGlobalIndexedSequence(clause)
}
).toList()
val filtered = partialResult.filter { it.innerClause matches clause }
filtered.asSequence().forEach { it.removeFromIndex() }
invalidCache(filtered.asSequence())
filtered.asSequence()
})
.filter { it.innerClause matches clause }
.map { it.removeFromIndex(); it }
.buffered()
}
else {
arities[clause.nestedArity()]?.retractAllIndexed(clause)?.let {
invalidCache(it)
it
} ?: emptySequence()
arities[clause.nestedArity()]?.retractAllIndexed(clause)?.invalidatingCacheIfNonEmpty()
?: emptySequence()
}

override fun extractGlobalIndexedSequence(clause: Clause): Sequence<SituatedIndexedClause> {
Expand All @@ -191,10 +175,8 @@ internal sealed class FunctorNode : ReteNode {
private fun IndexedClause.nestedArity(): Int =
this.innerClause.head!!.arityOfNestedFirstArgument(nestingLevel)

private fun invalidCache(result: Sequence<*>) {
if (result.any()) {
theoryCache.invalidate()
}
override fun invalidateCache() {
theoryCache.invalidate()
}

private fun regenerateCache(): MutableList<SituatedIndexedClause> =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package it.unibo.tuprolog.collections.rete.custom.nodes

import it.unibo.tuprolog.collections.rete.custom.ReteNode
import it.unibo.tuprolog.collections.rete.custom.TopLevelReteNode

internal interface FunctorRete : ReteNode,
TopLevelReteNode
Loading

0 comments on commit 4e1fdcd

Please sign in to comment.