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
|
||||
|
||||
/**
|
||||
* 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].
|
||||
* Resets journal position to specified position.
|
||||
* Moves [cursor] before [pastPos], so that [ChunkReader.next] is [pastPos].
|
||||
* 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.
|
||||
* @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)
|
||||
|
||||
|
|
@ -92,7 +98,7 @@ interface MatchJournal : Iterable<MatchJournal.Chunk>, EvidenceSource {
|
|||
* Replay activated and discarded occurrences logged in journal between current
|
||||
* and provided positions. Advances journal position to specified position.
|
||||
* 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)
|
||||
|
||||
|
|
@ -131,6 +137,12 @@ interface MatchJournal : Iterable<MatchJournal.Chunk>, EvidenceSource {
|
|||
*/
|
||||
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 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 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) {
|
||||
moveToPastRemoving(pastPos) {
|
||||
private fun reset(pastPos: MatchJournal.Pos, removing: Boolean) {
|
||||
__cursor.moveToPastRemoving(pastPos) {
|
||||
popAncestor()
|
||||
resetOccurrences(it.entries())
|
||||
removing
|
||||
removing && it !== pastPos.chunk
|
||||
}
|
||||
// drop occurrences at final chunk
|
||||
if (removing) current.entries = current.entries.subList(0, pastPos.entriesCount)
|
||||
resetOccurrences(current.entries.drop(pastPos.entriesCount))
|
||||
if (removing) with(pastPos.chunk as ChunkImpl) {
|
||||
entries = entries.subList(0, pastPos.entriesCount)
|
||||
}
|
||||
}
|
||||
|
||||
private fun popAncestor() {
|
||||
|
|
@ -324,8 +330,9 @@ internal open class MatchJournalImpl(
|
|||
|
||||
|
||||
/**
|
||||
* Walk in journal in direct order ([from] -> [next])
|
||||
* while applying [action] to each visited [Chunk].
|
||||
* Walk in journal in direct order ([from] -> [current])
|
||||
* while applying [action] to each visited [Chunk]
|
||||
* (not including [from], but including [__current]).
|
||||
* No journal state is changed, except by [action] effects
|
||||
* (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])
|
||||
* while applying [action] to each visited [Chunk]
|
||||
* and removing it if [action] return [true] for it.
|
||||
* Walk in journal in inverse order ([pastPos] <- [current]) while
|
||||
* applying [action] to each [Chunk] (including [pastPos])
|
||||
* 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) {
|
||||
while (!atStart()) {
|
||||
__current = it.previous()
|
||||
if (action(__current)) {
|
||||
it.remove()
|
||||
}
|
||||
if (this at pastPos) {
|
||||
it.next() // make it point right after _previous_
|
||||
__current = it.previous()
|
||||
it.next() // make it point right after __current
|
||||
updateNext()
|
||||
return
|
||||
}
|
||||
if (action(current)) {
|
||||
it.remove()
|
||||
}
|
||||
}
|
||||
this assertAt pastPos
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue