mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
[fleet] implement OpsIterator
An iterator to iterate over operation's ops back-and-forth. GitOrigin-RevId: 5ea0253dc3598f2e3396374575f921acf382c0c5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
75c4740409
commit
8832f4362f
@@ -38,6 +38,89 @@ sealed class Op {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OpsIterator(
|
||||||
|
private val owner: Any?,
|
||||||
|
private var cursor: Rope.Cursor<Array<Op>>?,
|
||||||
|
private val size: Int,
|
||||||
|
private var index: Int = 0,
|
||||||
|
private var elementIndex: Int = 0
|
||||||
|
): Iterator<Op> {
|
||||||
|
sealed interface Pos {
|
||||||
|
object Begin: Pos
|
||||||
|
object End: Pos
|
||||||
|
data class LenBefore(val offset: Int): Pos
|
||||||
|
data class LenAfter(val offset: Int): Pos
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): Op {
|
||||||
|
require(hasNext())
|
||||||
|
|
||||||
|
if (elementIndex >= cursor!!.element.size) {
|
||||||
|
cursor = cursor!!.next(owner)
|
||||||
|
elementIndex = 0
|
||||||
|
}
|
||||||
|
val op = cursor!!.element[elementIndex]
|
||||||
|
++elementIndex
|
||||||
|
++index
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return cursor != null && index < size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prev(): Op {
|
||||||
|
require(hasPrev())
|
||||||
|
|
||||||
|
if (elementIndex == 0) {
|
||||||
|
cursor = cursor!!.prev(owner)
|
||||||
|
elementIndex = cursor!!.element.size
|
||||||
|
}
|
||||||
|
--elementIndex
|
||||||
|
--index
|
||||||
|
return cursor!!.element[elementIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasPrev(): Boolean {
|
||||||
|
return index > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun scanTo(pos: Pos) {
|
||||||
|
when (pos) {
|
||||||
|
Pos.Begin -> {
|
||||||
|
cursor = cursor!!.scan(owner, OperationMonoid.Count, 0)
|
||||||
|
index = 0
|
||||||
|
elementIndex = 0
|
||||||
|
}
|
||||||
|
Pos.End -> {
|
||||||
|
cursor = cursor!!.scan(owner, OperationMonoid.Count, size)
|
||||||
|
index = size
|
||||||
|
elementIndex = MAX_LEAF_SIZE
|
||||||
|
}
|
||||||
|
is Pos.LenBefore -> {
|
||||||
|
val c = cursor!!
|
||||||
|
cursor = c.scan(owner, OperationMonoid.LenBefore, pos.offset)
|
||||||
|
elementIndex = 0
|
||||||
|
index = c.size(OperationMonoid.Count)
|
||||||
|
while (elementIndex < c.element.size && c.element[elementIndex].lenBefore <= pos.offset) {
|
||||||
|
++elementIndex
|
||||||
|
++index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Pos.LenAfter -> {
|
||||||
|
val c = cursor!!
|
||||||
|
cursor = c.scan(owner, OperationMonoid.LenAfter, pos.offset)
|
||||||
|
elementIndex = 0
|
||||||
|
index = c.size(OperationMonoid.Count)
|
||||||
|
while (elementIndex < c.element.size && c.element[elementIndex].lenAfter <= pos.offset) {
|
||||||
|
++elementIndex
|
||||||
|
++index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After introducing Replace operation there still exists two asymmetries:
|
* After introducing Replace operation there still exists two asymmetries:
|
||||||
* 1. Insert operations at the same place do not commute, so that {transform} function is not commutative
|
* 1. Insert operations at the same place do not commute, so that {transform} function is not commutative
|
||||||
@@ -52,13 +135,20 @@ sealed class Op {
|
|||||||
class Operation(internal val rope: OpsRope) {
|
class Operation(internal val rope: OpsRope) {
|
||||||
constructor(ops: List<Op>): this(OperationMonoid.ropeOf(listOf(ops.toTypedArray())))
|
constructor(ops: List<Op>): this(OperationMonoid.ropeOf(listOf(ops.toTypedArray())))
|
||||||
|
|
||||||
val ops: Sequence<Op> get() = sequence {
|
val ops: Sequence<Op> get() = sequence { yieldAll(begin()) }
|
||||||
|
|
||||||
|
fun begin(): OpsIterator {
|
||||||
val owner = Any()
|
val owner = Any()
|
||||||
var cursor: Rope.Cursor<Array<Op>>? = rope.cursor(owner)
|
val iterator = OpsIterator(owner, rope.cursor(owner), size)
|
||||||
while (cursor != null) {
|
iterator.scanTo(OpsIterator.Pos.Begin)
|
||||||
yieldAll(cursor.element.iterator())
|
return iterator
|
||||||
cursor = cursor.next(owner)
|
}
|
||||||
}
|
|
||||||
|
fun end(): OpsIterator {
|
||||||
|
val owner = Any()
|
||||||
|
val iterator = OpsIterator(owner, rope.cursor(owner), size)
|
||||||
|
iterator.scanTo(OpsIterator.Pos.End)
|
||||||
|
return iterator
|
||||||
}
|
}
|
||||||
|
|
||||||
val size: Int
|
val size: Int
|
||||||
|
|||||||
@@ -94,16 +94,25 @@ class Rope<T> internal constructor(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a pointer to the next chunk.
|
* Returns a pointer to the next chunk.
|
||||||
* If [owner] is the same as before, the previous Cursur is recycled and it's internals are reused for creating a new one.
|
* If [owner] is the same as before, the previous Cursor is recycled and it's internals are reused for creating a new one.
|
||||||
* */
|
* */
|
||||||
fun next(owner: Any?): Cursor<T>? =
|
fun next(owner: Any?): Cursor<T>? =
|
||||||
zipper.nextLeaf(owner, monoid)?.let { leaf ->
|
zipper.nextLeaf(owner, monoid)?.let { leaf ->
|
||||||
cursor(leaf)
|
cursor(leaf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to the prev chunk.
|
||||||
|
* If [owner] is the same as before, the previous Cursor is recycled and it's internals are reused for creating a new one.
|
||||||
|
* */
|
||||||
|
fun prev(owner: Any?): Cursor<T>? =
|
||||||
|
zipper.prevLeaf(owner, monoid)?.let { leaf ->
|
||||||
|
cursor(leaf)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a new rope, accomodating all changes made to the cursor.
|
* Builds a new rope, accomodating all changes made to the cursor.
|
||||||
* If [owner] is the same as before, the previous Cursur is recycled and it's internals are reused.
|
* If [owner] is the same as before, the previous Cursor is recycled and it's internals are reused.
|
||||||
* */
|
* */
|
||||||
fun rope(owner: Any?): Rope<T> =
|
fun rope(owner: Any?): Rope<T> =
|
||||||
zipper.rope(owner, monoid)
|
zipper.rope(owner, monoid)
|
||||||
|
|||||||
Reference in New Issue
Block a user