Skip to content

Commit 764b18a

Browse files
committed
work around scala/scala3#9631
by making sure we pat-mat against a known sub-type of `SkipList`
1 parent 0325e57 commit 764b18a

File tree

2 files changed

+86
-83
lines changed

2 files changed

+86
-83
lines changed

DottyLucre/data/src/main/scala/de/sciss/lucre/data/HASkipList.scala

Lines changed: 85 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
package de.sciss.lucre.data
1515

16+
import de.sciss.lucre.data.HASkipList.Node
1617
import de.sciss.lucre.stm.impl.MutableImpl
1718
import de.sciss.lucre.stm.{Base, Ident, NewImmutSerializer, Sink, TxSerializer, Txn, Var}
1819
import de.sciss.serial.{DataInput, DataOutput, Serializer}
@@ -81,32 +82,33 @@ object HASkipList {
8182
override def toString = "HASkipList.Map.serializer"
8283
}
8384

84-
def debugFindLevel[T <: Txn[T], A](list: SkipList[T, A, _], key: A)(implicit tx: T): Int = list match {
85-
case impl0: Impl[T, A, _] => // wrong warning
86-
val h = impl0.height
87-
88-
@tailrec
89-
def stepRight[E](impl: Impl[T, A, E], n: Node[T, A, E], lvl: Int): Int = {
90-
val idx = impl.indexInNodeR(key, n)
91-
if (idx < 0) lvl
92-
else if (n.isLeaf) -1
93-
else {
94-
val c = n.asBranch.down(idx)
95-
if (idx < n.size - 1) stepLeft(impl, c, lvl - 1) else stepRight(impl, c, lvl - 1)
85+
def debugFindLevel[T <: Txn[T], A, E](list: SkipList[T, A, E], key: A)(implicit tx: T): Int =
86+
list match {
87+
case impl0: HASkipList[T, A, E] =>
88+
val h = impl0.height
89+
90+
@tailrec
91+
def stepRight(impl: HASkipList[T, A, E], n: Node[T, A, E], lvl: Int): Int = {
92+
val idx = impl.indexInNodeR(key, n)
93+
if (idx < 0) lvl
94+
else if (n.isLeaf) -1
95+
else {
96+
val c = n.asBranch.down(idx)
97+
if (idx < n.size - 1) stepLeft(impl, c, lvl - 1) else stepRight(impl, c, lvl - 1)
98+
}
9699
}
97-
}
98-
99-
@tailrec
100-
def stepLeft[E](impl: Impl[T, A, E], n: Node[T, A, E], lvl: Int): Int = {
101-
val idx = impl.indexInNodeL(key, n)
102-
if (idx < 0) lvl else if (n.isLeaf) -1 else stepLeft(impl, n.asBranch.down(idx), lvl - 1)
103-
}
104-
105-
val c = impl0.top.orNull // topN
106-
if (c eq null) -1 else stepRight(impl0, c, h)
107-
108-
case _ => sys.error(s"Not a HA Skip List: $list")
109-
}
100+
101+
@tailrec
102+
def stepLeft[E](impl: HASkipList[T, A, E], n: Node[T, A, E], lvl: Int): Int = {
103+
val idx = impl.indexInNodeL(key, n)
104+
if (idx < 0) lvl else if (n.isLeaf) -1 else stepLeft(impl, n.asBranch.down(idx), lvl - 1)
105+
}
106+
107+
val c = impl0.top.orNull // topN
108+
if (c eq null) -1 else stepRight(impl0, c, h)
109+
110+
case _ => sys.error(s"Not a HA Skip List: $list")
111+
}
110112

111113
private final class SetImpl[T <: Txn[T], A](val id: Ident[T], val minGap: Int,
112114
protected val keyObserver: SkipList.KeyObserver[T, A],
@@ -268,20 +270,14 @@ object HASkipList {
268270
}
269271

270272
private sealed trait Impl[T <: Txn[T], /* @spec(KeySpec) */ A, E]
271-
extends HeadOrBranch[T, A, E] with TxSerializer[T, Node[T, A, E]] with MutableImpl[T] {
273+
extends HASkipList[T, A, E] with HeadOrBranch[T, A, E] with TxSerializer[T, Node[T, A, E]] with MutableImpl[T] {
272274
impl =>
273275

274276
// ---- abstract ----
275277

276278
protected def downNode: Var[T, Node[T, A, E]]
277-
protected def minGap: Int
278-
protected def ordering: scala.Ordering[A]
279279
protected def keyObserver: SkipList.KeyObserver[T, A]
280280

281-
def keySerializer: NewImmutSerializer[A]
282-
283-
def id: Ident[T]
284-
285281
def writeEntry(entry: E, out: DataOutput): Unit
286282

287283
protected def newLeaf(entry: E): Leaf[T, A, E]
@@ -326,20 +322,20 @@ object HASkipList {
326322
// }
327323
}
328324

329-
protected final def disposeData()(implicit tx: T): Unit =
325+
protected override final def disposeData()(implicit tx: T): Unit =
330326
downNode.dispose()
331327

332-
def size(implicit tx: T): Int = {
328+
override def size(implicit tx: T): Int = {
333329
val c = topN
334330
if (c eq null) 0 else c.leafSizeSum - 1
335331
}
336332

337-
final def maxGap: Int = (minGap << 1) + 1 // aka arrMaxSz - 1
333+
final override def maxGap: Int = (minGap << 1) + 1 // aka arrMaxSz - 1
338334

339-
final def isEmpty (implicit tx: T): Boolean = topN eq null
340-
final def nonEmpty(implicit tx: T): Boolean = !isEmpty
335+
final override def isEmpty (implicit tx: T): Boolean = topN eq null
336+
final override def nonEmpty(implicit tx: T): Boolean = !isEmpty
341337

342-
final def height(implicit tx: T): Int = {
338+
final override def height(implicit tx: T): Int = {
343339
var n = topN
344340
if (n eq null) 0
345341
else {
@@ -356,12 +352,12 @@ object HASkipList {
356352

357353
@inline protected final def topN(implicit tx: T): Node[T, A, E] = downNode()
358354

359-
final def debugPrint()(implicit tx: T): String = topN.printNode(isRight = true).mkString("\n")
355+
final override def debugPrint()(implicit tx: T): String = topN.printNode(isRight = true).mkString("\n")
360356

361-
final def toIndexedSeq(implicit tx: T): Vec [E] = fillBuilder(Vector.newBuilder)
362-
final def toList (implicit tx: T): List[E] = fillBuilder(List .newBuilder)
363-
final def toSeq (implicit tx: T): Seq [E] = fillBuilder(Seq .newBuilder)
364-
final def toSet (implicit tx: T): ISet[E] = fillBuilder(ISet .newBuilder)
357+
final override def toIndexedSeq(implicit tx: T): Vec [E] = fillBuilder(Vector.newBuilder)
358+
final override def toList (implicit tx: T): List[E] = fillBuilder(List .newBuilder)
359+
final override def toSeq (implicit tx: T): Seq [E] = fillBuilder(Seq .newBuilder)
360+
final override def toSet (implicit tx: T): ISet[E] = fillBuilder(ISet .newBuilder)
365361

366362
private[this] def fillBuilder[Res](b: mutable.Builder[E, Res])(implicit tx: T): Res = {
367363
val i = iterator
@@ -380,13 +376,13 @@ object HASkipList {
380376
}
381377
}
382378

383-
final def head(implicit tx: T): E = {
379+
final override def head(implicit tx: T): E = {
384380
val n0 = topN
385381
if (n0 eq null) throw new NoSuchElementException("head of empty list")
386382
else headImpl(n0)
387383
}
388384

389-
final def headOption(implicit tx: T): Option[E] = {
385+
final override def headOption(implicit tx: T): Option[E] = {
390386
val n0 = topN
391387
if (n0 eq null) None
392388
else Some(headImpl(n0))
@@ -401,13 +397,13 @@ object HASkipList {
401397
}
402398
}
403399

404-
final def last(implicit tx: T): E = {
400+
final override def last(implicit tx: T): E = {
405401
val n0 = topN
406402
if (n0 eq null) throw new NoSuchElementException("last of empty list")
407403
else lastImpl(n0)
408404
}
409405

410-
final def lastOption(implicit tx: T): Option[E] = {
406+
final override def lastOption(implicit tx: T): Option[E] = {
411407
val n0 = topN
412408
if (n0 eq null) None
413409
else Some(lastImpl(n0))
@@ -421,7 +417,7 @@ object HASkipList {
421417
* @return if `Some`, holds the leaf and index for the floor element (whose key is <= the search key),
422418
* if `None`, there is no key smaller than or equal to the search key in the list
423419
*/
424-
final def floor(key: A)(implicit tx: T): Option[E] = {
420+
final override def floor(key: A)(implicit tx: T): Option[E] = {
425421
// the algorithm is as follows: find the index of the search key in the current level.
426422
// if the key was found, just go down straight to the leaf. if not:
427423
// - the index points to an element greater than the search key
@@ -479,7 +475,7 @@ object HASkipList {
479475
* @return if `Some`, holds the leaf and index for the ceiling element (whose key is >= the search key),
480476
* if `None`, there is no key greater than or equal to the search key in the list
481477
*/
482-
final def ceil(key: A)(implicit tx: T): Option[E] = {
478+
final override def ceil(key: A)(implicit tx: T): Option[E] = {
483479
@tailrec
484480
def step(n: Node[T, A, E], isRight: Boolean): Option[E] = {
485481
val idx = if (isRight) indexInNodeR(key, n) else indexInNodeL(key, n)
@@ -495,7 +491,7 @@ object HASkipList {
495491
if (c eq null) None else step(c, isRight = true)
496492
}
497493

498-
final def isomorphicQuery(ord: Ordered[T, A])(implicit tx: T): (E, Int) = {
494+
final override def isomorphicQuery(ord: Ordered[T, A])(implicit tx: T): (E, Int) = {
499495
def isoIndexR(n: Node[T, A, E]): Int = {
500496
var idx = 0
501497
val sz = n.size - 1
@@ -560,7 +556,7 @@ object HASkipList {
560556

561557
// ---- set support ----
562558

563-
final def contains(v: A)(implicit tx: T): Boolean = {
559+
final override def contains(v: A)(implicit tx: T): Boolean = {
564560
@tailrec
565561
def stepRight(n: Node[T, A, E]): Boolean = {
566562
val idx = indexInNodeR(v, n)
@@ -582,15 +578,6 @@ object HASkipList {
582578
if (c eq null) false else stepRight(c)
583579
}
584580

585-
/** Finds the right-most key which
586-
* is greater than or equal to the query key.
587-
*
588-
* @param key the key to search for
589-
* @param n the branch or leaf from which to go down
590-
*
591-
* @return the index to go down (a node whose key is greater than `key`),
592-
* or `-(index+1)` if `key` was found at `index`
593-
*/
594581
final /*protected */ def indexInNodeR(key: A, n: Node[T, A, E])(implicit tx: T): Int = {
595582
var idx = 0
596583
val sz = n.size - 1
@@ -696,7 +683,7 @@ object HASkipList {
696683
}
697684
}
698685

699-
final def -=(key: A)(implicit tx: T): this.type = {
686+
final override def -=(key: A)(implicit tx: T): this.type = {
700687
removeEntry(key); this
701688
}
702689

@@ -1064,9 +1051,11 @@ object HASkipList {
10641051
}
10651052

10661053
sealed trait Node[T <: Txn[T], A, E] {
1054+
10671055
private[HASkipList] def removeColumn(idx: Int)(implicit tx: T, list: Impl[T, A, E]): Node[T, A, E]
10681056

10691057
def size: Int
1058+
10701059
def key(i: Int): A
10711060

10721061
private[HASkipList] def write(out: DataOutput)(implicit list: Impl[T, A, E]): Unit
@@ -1130,34 +1119,35 @@ object HASkipList {
11301119
private final class SetLeaf[T <: Txn[T], A](private[HASkipList] val entries: Vector[A])
11311120
extends Leaf[T, A, A] {
11321121

1133-
protected def copy(newEntries: Vector[A]): Leaf[T, A, A] = new SetLeaf(newEntries)
1122+
protected override def copy(newEntries: Vector[A]): Leaf[T, A, A] = new SetLeaf(newEntries)
11341123

1135-
def key(idx: Int): A = entries(idx)
1124+
override def key(idx: Int): A = entries(idx)
11361125
}
11371126

11381127
private final class MapLeaf[T <: Txn[T], A, B](private[HASkipList] val entries: Vector[(A, B)])
11391128
extends Leaf[T, A, (A, B)] {
11401129

1141-
protected def copy(newEntries: Vector[(A, B)]): Leaf[T, A, (A, B)] = new MapLeaf(newEntries)
1130+
protected override def copy(newEntries: Vector[(A, B)]): Leaf[T, A, (A, B)] = new MapLeaf(newEntries)
11421131

1143-
def key(idx: Int): A = entries(idx)._1
1132+
override def key(idx: Int): A = entries(idx)._1
11441133
}
11451134

11461135
sealed trait Leaf[T <: Txn[T], A, E] extends Node[T, A, E] {
11471136
override def toString: String = entries.mkString("Leaf(", ",", ")")
11481137

11491138
private[HASkipList] def entries: Vector[E]
1139+
11501140
final def entry(idx: Int): E = entries(idx)
11511141

11521142
protected def copy(newEntries: Vector[E]): Leaf[T, A, E]
11531143

1154-
final def size: Int = entries.size
1144+
final override def size: Int = entries.size
11551145

1156-
final def isLeaf: Boolean = true
1157-
final def isBranch: Boolean = false
1146+
final override def isLeaf: Boolean = true
1147+
final override def isBranch: Boolean = false
11581148

1159-
final def asLeaf: Leaf[T, A, E] = this
1160-
final def asBranch: Branch[T, A, E] = opNotSupported
1149+
final override def asLeaf: Leaf[T, A, E] = this
1150+
final override def asBranch: Branch[T, A, E] = opNotSupported
11611151

11621152
private[HASkipList] final def leafSizeSum(implicit tx: T): Int = size
11631153

@@ -1264,11 +1254,11 @@ object HASkipList {
12641254

12651255
override def toString: String = keys.mkString("Branch(", ",", ")")
12661256

1267-
def isLeaf: Boolean = false
1268-
def isBranch: Boolean = true
1257+
override def isLeaf: Boolean = false
1258+
override def isBranch: Boolean = true
12691259

1270-
def asLeaf: Leaf [T, A, B] = opNotSupported
1271-
def asBranch: Branch[T, A, B] = this
1260+
override def asLeaf: Leaf [T, A, B] = opNotSupported
1261+
override def asBranch: Branch[T, A, B] = this
12721262

12731263
private[HASkipList] def mergeRight(sib: Node[T, A, B])(implicit tx: T): Node[T, A, B] = {
12741264
val bSib = sib.asBranch
@@ -1320,9 +1310,9 @@ object HASkipList {
13201310
}
13211311
}
13221312

1323-
def key(idx: Int): A = keys(idx)
1313+
override def key(idx: Int): A = keys(idx)
13241314

1325-
def size: Int = keys.length
1315+
override def size: Int = keys.length
13261316

13271317
private[HASkipList] def downRef(i: Int): Var[T, Node[T, A, B]] = downs(i)
13281318

@@ -1453,9 +1443,7 @@ object HASkipList {
14531443
new SetSer[T, A](keyObserver)
14541444
}
14551445

1456-
sealed trait Set[T <: Txn[T], A] extends SkipList.Set[T, A] {
1457-
def top(implicit tx: T): Option[HASkipList.Set.Node[T, A]]
1458-
}
1446+
trait Set[T <: Txn[T], A] extends SkipList.Set[T, A] with HASkipList[T, A, A]
14591447

14601448
object Map {
14611449
type Node [T <: Txn[T], A, B] = HASkipList.Node [T, A, (A, B)]
@@ -1526,7 +1514,22 @@ object HASkipList {
15261514
new MapSer[T, A, B](keyObserver)
15271515
}
15281516

1529-
sealed trait Map[T <: Txn[T], /* @spec(KeySpec) */ A, /* @spec(ValueSpec) */ B] extends SkipList.Map[T, A, B] {
1530-
def top(implicit tx: T): Option[HASkipList.Node[T, A, (A, B)]]
1531-
}
1517+
trait Map[T <: Txn[T], /* @spec(KeySpec) */ A, /* @spec(ValueSpec) */ B]
1518+
extends SkipList.Map[T, A, B] with HASkipList[T, A, (A, B)]
1519+
}
1520+
trait HASkipList[T <: Txn[T], A, E] extends SkipList[T, A, E] {
1521+
def top(implicit tx: T): Option[HASkipList.Node[T, A, E]]
1522+
1523+
/** Finds the right-most key which
1524+
* is greater than or equal to the query key.
1525+
*
1526+
* @param key the key to search for
1527+
* @param n the branch or leaf from which to go down
1528+
*
1529+
* @return the index to go down (a node whose key is greater than `key`),
1530+
* or `-(index+1)` if `key` was found at `index`
1531+
*/
1532+
def indexInNodeR(key: A, n: HASkipList.Node[T, A, E])(implicit tx: T): Int
1533+
1534+
def indexInNodeL(key: A, n: HASkipList.Node[T, A, E])(implicit tx: T): Int
15321535
}

DottyLucre/data/src/main/scala/de/sciss/lucre/data/SkipList.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ object SkipList {
169169
}
170170
}
171171

172-
sealed trait SkipList[T <: Txn[T], /* @spec(KeySpec) */ A, /* @spec(ValueSpec) */ E] extends Mutable[Ident[T] /*S#Id*/, T] {
172+
/*sealed*/ trait SkipList[T <: Txn[T], /* @spec(KeySpec) */ A, /* @spec(ValueSpec) */ E] extends Mutable[Ident[T] /*S#Id*/, T] {
173173
/** Searches for the Branch of a given key.
174174
*
175175
* @param key the key to search for

0 commit comments

Comments
 (0)