Change a bit behavior of MatchJournal.reset* methods
Now after MatchJournal.reset(pos) cursor points before the `pos`, not at it. So cursor.next will return 'pos' It's required for MPSCR-67
This commit is contained in:
parent
2b46ab0413
commit
273d4dc4db
|
|
@ -76,15 +76,21 @@ interface MatchJournal : Iterable<MatchJournal.Chunk>, EvidenceSource {
|
||||||
val cursor: RemovingJournalIterator
|
val cursor: RemovingJournalIterator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset journal's position to the beginning, don't modify journal.
|
* Same as [resetCursor], moves [cursor] before [initialChunk].
|
||||||
*/
|
*/
|
||||||
fun resetCursor()
|
fun resetCursor() = resetCursor(Pos(initialChunk(), 0))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erase part of the journal between [currentPos] and [pastPos].
|
* Moves [cursor] before [pastPos], so that [ChunkReader.next] is [pastPos].
|
||||||
* Resets journal position to specified position.
|
* Doesn't modify journal contents, as opposed to [reset].
|
||||||
|
*/
|
||||||
|
fun resetCursor(pastPos: Pos)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase journal between [currentPos] (erased) and [pastPos] (not erased).
|
||||||
|
* Moves [cursor] at [pastPos], so that [ChunkReader.current] is [pastPos].
|
||||||
* @param pastPos position to reset to.
|
* @param pastPos position to reset to.
|
||||||
* @throws IllegalStateException when position is not from the past (relative to current pos).
|
* @throws IllegalStateException when position is not from the past (relative to [cursor]).
|
||||||
*/
|
*/
|
||||||
fun reset(pastPos: Pos)
|
fun reset(pastPos: Pos)
|
||||||
|
|
||||||
|
|
@ -92,7 +98,7 @@ interface MatchJournal : Iterable<MatchJournal.Chunk>, EvidenceSource {
|
||||||
* Replay activated and discarded occurrences logged in journal between current
|
* Replay activated and discarded occurrences logged in journal between current
|
||||||
* and provided positions. Advances journal position to specified position.
|
* and provided positions. Advances journal position to specified position.
|
||||||
* Idempotent operation (can be called multiple times on same [Pos]]).
|
* Idempotent operation (can be called multiple times on same [Pos]]).
|
||||||
* @throws IllegalStateException when position is not from the future (relative to current pos).
|
* @throws IllegalStateException when [futurePos] is not from the future (relative to [cursor]).
|
||||||
*/
|
*/
|
||||||
fun replay(futurePos: Pos)
|
fun replay(futurePos: Pos)
|
||||||
|
|
||||||
|
|
@ -131,6 +137,12 @@ interface MatchJournal : Iterable<MatchJournal.Chunk>, EvidenceSource {
|
||||||
*/
|
*/
|
||||||
fun isKnown(chunk: Chunk): Boolean
|
fun isKnown(chunk: Chunk): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as [isKnown], but for [Occurrence].
|
||||||
|
* Returns [true] for indexed [Occurrence]s.
|
||||||
|
*/
|
||||||
|
fun isKnown(occ: Occurrence): Boolean = activatingChunkOf(occ) != null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns [Chunk] where [occ] was activated.
|
* Returns [Chunk] where [occ] was activated.
|
||||||
* Returns null for non-principal occurrences & those not from indexed session.
|
* Returns null for non-principal occurrences & those not from indexed session.
|
||||||
|
|
|
||||||
|
|
@ -189,19 +189,25 @@ internal open class MatchJournalImpl(
|
||||||
override fun isFront(): Boolean = __cursor.atEnd()
|
override fun isFront(): Boolean = __cursor.atEnd()
|
||||||
|
|
||||||
|
|
||||||
override fun reset(pastPos: MatchJournal.Pos) = reset(pastPos, true)
|
override fun reset(pastPos: MatchJournal.Pos) {
|
||||||
|
reset(pastPos, true)
|
||||||
|
replay(pastPos)
|
||||||
|
}
|
||||||
|
|
||||||
override fun resetCursor() = reset(Pos(initialChunk(), 0), false)
|
override fun resetCursor(pastPos: Pos) {
|
||||||
|
reset(pastPos, false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun reset(pastPos: MatchJournal.Pos, removing: Boolean) = with(__cursor) {
|
private fun reset(pastPos: MatchJournal.Pos, removing: Boolean) {
|
||||||
moveToPastRemoving(pastPos) {
|
__cursor.moveToPastRemoving(pastPos) {
|
||||||
popAncestor()
|
popAncestor()
|
||||||
resetOccurrences(it.entries())
|
resetOccurrences(it.entries())
|
||||||
removing
|
removing && it !== pastPos.chunk
|
||||||
}
|
}
|
||||||
// drop occurrences at final chunk
|
// drop occurrences at final chunk
|
||||||
if (removing) current.entries = current.entries.subList(0, pastPos.entriesCount)
|
if (removing) with(pastPos.chunk as ChunkImpl) {
|
||||||
resetOccurrences(current.entries.drop(pastPos.entriesCount))
|
entries = entries.subList(0, pastPos.entriesCount)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun popAncestor() {
|
private fun popAncestor() {
|
||||||
|
|
@ -324,8 +330,9 @@ internal open class MatchJournalImpl(
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walk in journal in direct order ([from] -> [next])
|
* Walk in journal in direct order ([from] -> [current])
|
||||||
* while applying [action] to each visited [Chunk].
|
* while applying [action] to each visited [Chunk]
|
||||||
|
* (not including [from], but including [__current]).
|
||||||
* No journal state is changed, except by [action] effects
|
* No journal state is changed, except by [action] effects
|
||||||
* (i.e. no reset or replay of occurrences is performed).
|
* (i.e. no reset or replay of occurrences is performed).
|
||||||
*/
|
*/
|
||||||
|
|
@ -343,21 +350,24 @@ internal open class MatchJournalImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walk in journal in inverse order ([next] -> [pastPos])
|
* Walk in journal in inverse order ([pastPos] <- [current]) while
|
||||||
* while applying [action] to each visited [Chunk]
|
* applying [action] to each [Chunk] (including [pastPos])
|
||||||
* and removing it if [action] return [true] for it.
|
* and removing it if [action] returns true for it.
|
||||||
|
*
|
||||||
|
* Contract: after the call [__next] points to [pastPos].
|
||||||
*/
|
*/
|
||||||
inline fun moveToPastRemoving(pastPos: Pos, action: (Chunk) -> Boolean) {
|
inline fun moveToPastRemoving(pastPos: Pos, action: (Chunk) -> Boolean) {
|
||||||
while (!atStart()) {
|
while (!atStart()) {
|
||||||
__current = it.previous()
|
__current = it.previous()
|
||||||
|
if (action(__current)) {
|
||||||
|
it.remove()
|
||||||
|
}
|
||||||
if (this at pastPos) {
|
if (this at pastPos) {
|
||||||
it.next() // make it point right after _previous_
|
__current = it.previous()
|
||||||
|
it.next() // make it point right after __current
|
||||||
updateNext()
|
updateNext()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (action(current)) {
|
|
||||||
it.remove()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this assertAt pastPos
|
this assertAt pastPos
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue