@@ -16,7 +16,6 @@ package concurrent
1616
1717import scala .language .`2.13`
1818import language .experimental .captureChecking
19- import scala .language .unsafeNulls
2019
2120import java .util .concurrent .atomic ._
2221import scala .{unchecked => uc }
@@ -35,20 +34,20 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
3534
3635 def this (g : Gen , equiv : Equiv [K ]) = this (null , g, equiv)
3736
38- def WRITE (nval : MainNode [K , V ]) = INodeBase .updater.set(this , nval)
37+ def WRITE (nval : MainNode [K , V ] | Null ) = INodeBase .updater.set(this , nval)
3938
4039 def CAS (old : MainNode [K , V ], n : MainNode [K , V ]) = INodeBase .updater.compareAndSet(this , old, n)
4140
42- def gcasRead (ct : TrieMap [K , V ]): MainNode [K , V ] = GCAS_READ (ct)
41+ def gcasRead (ct : TrieMap [K , V ]): MainNode [K , V ] | Null = GCAS_READ (ct)
4342
44- def GCAS_READ (ct : TrieMap [K , V ]): MainNode [K , V ] = {
43+ def GCAS_READ (ct : TrieMap [K , V ]): MainNode [K , V ] | Null = {
4544 val m = /* READ*/ mainnode
4645 val prevval : MainNode [K , V ] | Null = /* READ*/ m.prev
4746 if (prevval eq null ) m
4847 else GCAS_Complete (m, ct)
4948 }
5049
51- @ tailrec private def GCAS_Complete (m : MainNode [K , V ], ct : TrieMap [K , V ]): MainNode [K , V ] = if (m eq null ) null else {
50+ @ tailrec private def GCAS_Complete (m : MainNode [K , V ] | Null , ct : TrieMap [K , V ]): MainNode [K , V ] | Null = if (m eq null ) null else {
5251 // complete the GCAS
5352 val prev : MainNode [K , V ] | Null = /* READ*/ m.prev
5453 val ctr = ct.readRoot(abort = true )
@@ -74,7 +73,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
7473 else GCAS_Complete (m, ct)
7574 } else {
7675 // try to abort
77- m.CAS_PREV (prev, new FailedNode (prev))
76+ m.CAS_PREV (prev, new FailedNode (prev.nn ))
7877 GCAS_Complete (/* READ*/ mainnode, ct)
7978 }
8079 }
@@ -107,7 +106,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
107106 *
108107 * @return true if successful, false otherwise
109108 */
110- @ tailrec def rec_insert (k : K , v : V , hc : Int , lev : Int , parent : INode [K , V ], startgen : Gen , ct : TrieMap [K , V ]): Boolean = {
109+ @ tailrec def rec_insert (k : K , v : V , hc : Int , lev : Int , parent : INode [K , V ] | Null , startgen : Gen , ct : TrieMap [K , V ]): Boolean = {
111110 val m = GCAS_READ (ct) // use -Yinline!
112111
113112 m match {
@@ -141,7 +140,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
141140 GCAS (cn, ncnode, ct)
142141 }
143142 case tn : TNode [K , V ] =>
144- clean(parent, ct, lev - 5 )
143+ clean(parent.nn , ct, lev - 5 )
145144 false
146145 case ln : LNode [K , V ] => // 3) an l-node
147146 val nn = ln.inserted(k, v)
@@ -163,7 +162,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
163162 *
164163 * @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key)
165164 */
166- @ tailrec def rec_insertif (k : K , v : V , hc : Int , cond : AnyRef , fullEquals : Boolean , lev : Int , parent : INode [K , V ], startgen : Gen , ct : TrieMap [K , V ]): Option [V ] = {
165+ @ tailrec def rec_insertif (k : K , v : V , hc : Int , cond : AnyRef , fullEquals : Boolean , lev : Int , parent : INode [K , V ] | Null , startgen : Gen , ct : TrieMap [K , V ]): Option [V ] | Null = {
167166 val m = GCAS_READ (ct) // use -Yinline!
168167
169168 m match {
@@ -220,7 +219,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
220219 case otherv => None
221220 }
222221 case sn : TNode [K , V ] =>
223- clean(parent, ct, lev - 5 )
222+ clean(parent.nn , ct, lev - 5 )
224223 null
225224 case ln : LNode [K , V ] => // 3) an l-node
226225 def insertln () = {
@@ -259,7 +258,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
259258 * @return NO_SUCH_ELEMENT_SENTINEL if no value has been found, RESTART if the operation wasn't successful,
260259 * or any other value otherwise
261260 */
262- @ tailrec def rec_lookup (k : K , hc : Int , lev : Int , parent : INode [K , V ], startgen : Gen , ct : TrieMap [K , V ]): AnyRef = {
261+ @ tailrec def rec_lookup (k : K , hc : Int , lev : Int , parent : INode [K , V ] | Null , startgen : Gen , ct : TrieMap [K , V ]): AnyRef = {
263262 val m = GCAS_READ (ct) // use -Yinline!
264263
265264 m match {
@@ -286,7 +285,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
286285 }
287286 case tn : TNode [_, _] => // 3) non-live node
288287 def cleanReadOnly (tn : TNode [K , V ]) = if (ct.nonReadOnly) {
289- clean(parent, ct, lev - 5 )
288+ clean(parent.nn , ct, lev - 5 )
290289 RESTART
291290 } else {
292291 if (tn.hc == hc && tn.k == k) tn.v.asInstanceOf [AnyRef ]
@@ -314,9 +313,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
314313 removalPolicy : Int ,
315314 hc : Int ,
316315 lev : Int ,
317- parent : INode [K , V ],
316+ parent : INode [K , V ] | Null ,
318317 startgen : Gen ,
319- ct : TrieMap [K , V ]): Option [V ] = {
318+ ct : TrieMap [K , V ]): Option [V ] | Null = {
320319
321320 GCAS_READ (ct) match {
322321 case cn : CNode [K , V ] =>
@@ -344,8 +343,8 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
344343
345344 if (res == None || (res eq null )) res
346345 else {
347- @ tailrec def cleanParent (nonlive : AnyRef ): Unit = {
348- val cn = parent.GCAS_READ (ct)
346+ @ tailrec def cleanParent (nonlive : AnyRef | Null ): Unit = {
347+ val cn = parent.nn. GCAS_READ (ct)
349348 cn match {
350349 case cn : CNode [K , V ] =>
351350 val idx = (hc >>> (lev - 5 )) & 0x1f
@@ -358,7 +357,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
358357 if (sub eq this ) (nonlive : @ uc) match {
359358 case tn : TNode [K , V ] @ uc =>
360359 val ncn = cn.updatedAt(pos, tn.copyUntombed, gen).toContracted(lev - 5 )
361- if (! parent.GCAS (cn, ncn, ct))
360+ if (! parent.nn. GCAS (cn, ncn, ct))
362361 if (ct.readRoot().gen == startgen) cleanParent(nonlive)
363362 }
364363 }
@@ -376,7 +375,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
376375 }
377376 }
378377 case tn : TNode [K , V ] =>
379- clean(parent, ct, lev - 5 )
378+ clean(parent.nn , ct, lev - 5 )
380379 null
381380 case ln : LNode [K , V ] =>
382381 if (removalPolicy == RemovalPolicy .Always ) {
@@ -404,10 +403,10 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
404403 def isNullInode (ct : TrieMap [K , V ]) = GCAS_READ (ct) eq null
405404
406405 def cachedSize (ct : TrieMap [K , V ]): Int =
407- GCAS_READ (ct).cachedSize(ct)
406+ GCAS_READ (ct).nn. cachedSize(ct)
408407
409408 def knownSize (ct : TrieMap [K , V ]): Int =
410- GCAS_READ (ct).knownSize()
409+ GCAS_READ (ct).nn. knownSize()
411410
412411 /* this is a quiescent method! */
413412 def string (lev : Int ) = " %sINode -> %s" .format(" " * lev, mainnode match {
@@ -690,7 +689,7 @@ private[concurrent] case class RDCSS_Descriptor[K, V](old: INode[K, V], expected
690689 * For details, see: [[http://lampwww.epfl.ch/~prokopec/ctries-snapshot.pdf ]]
691690 */
692691@ SerialVersionUID (- 5212455458703321708L )
693- final class TrieMap [K , V ] private (r : AnyRef , rtupd : AtomicReferenceFieldUpdater [TrieMap [K , V ], AnyRef ], hashf : Hashing [K ], ef : Equiv [K ])
692+ final class TrieMap [K , V ] private (r : AnyRef , rtupd : AtomicReferenceFieldUpdater [TrieMap [K , V ], AnyRef ] | Null , hashf : Hashing [K ], ef : Equiv [K ])
694693 extends scala.collection.mutable.AbstractMap [K , V ]
695694 with scala.collection.concurrent.Map [K , V ]
696695 with scala.collection.mutable.MapOps [K , V , TrieMap , TrieMap [K , V ]]
@@ -788,8 +787,8 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater
788787 }
789788 }
790789
791- private def RDCSS_ROOT (ov : INode [K , V ], expectedmain : MainNode [K , V ], nv : INode [K , V ]): Boolean = {
792- val desc = RDCSS_Descriptor (ov, expectedmain, nv)
790+ private def RDCSS_ROOT (ov : INode [K , V ], expectedmain : MainNode [K , V ] | Null , nv : INode [K , V ]): Boolean = {
791+ val desc = RDCSS_Descriptor (ov, expectedmain.nn , nv)
793792 if (CAS_ROOT (ov, desc)) {
794793 RDCSS_Complete (abort = false )
795794 /* READ*/ desc.committed
0 commit comments