@@ -16,7 +16,6 @@ package concurrent
16
16
17
17
import scala .language .`2.13`
18
18
import language .experimental .captureChecking
19
- import scala .language .unsafeNulls
20
19
21
20
import java .util .concurrent .atomic ._
22
21
import scala .{unchecked => uc }
@@ -35,20 +34,20 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
35
34
36
35
def this (g : Gen , equiv : Equiv [K ]) = this (null , g, equiv)
37
36
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)
39
38
40
39
def CAS (old : MainNode [K , V ], n : MainNode [K , V ]) = INodeBase .updater.compareAndSet(this , old, n)
41
40
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)
43
42
44
- def GCAS_READ (ct : TrieMap [K , V ]): MainNode [K , V ] = {
43
+ def GCAS_READ (ct : TrieMap [K , V ]): MainNode [K , V ] | Null = {
45
44
val m = /* READ*/ mainnode
46
45
val prevval : MainNode [K , V ] | Null = /* READ*/ m.prev
47
46
if (prevval eq null ) m
48
47
else GCAS_Complete (m, ct)
49
48
}
50
49
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 {
52
51
// complete the GCAS
53
52
val prev : MainNode [K , V ] | Null = /* READ*/ m.prev
54
53
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
74
73
else GCAS_Complete (m, ct)
75
74
} else {
76
75
// try to abort
77
- m.CAS_PREV (prev, new FailedNode (prev))
76
+ m.CAS_PREV (prev, new FailedNode (prev.nn ))
78
77
GCAS_Complete (/* READ*/ mainnode, ct)
79
78
}
80
79
}
@@ -107,7 +106,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
107
106
*
108
107
* @return true if successful, false otherwise
109
108
*/
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 = {
111
110
val m = GCAS_READ (ct) // use -Yinline!
112
111
113
112
m match {
@@ -141,7 +140,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
141
140
GCAS (cn, ncnode, ct)
142
141
}
143
142
case tn : TNode [K , V ] =>
144
- clean(parent, ct, lev - 5 )
143
+ clean(parent.nn , ct, lev - 5 )
145
144
false
146
145
case ln : LNode [K , V ] => // 3) an l-node
147
146
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
163
162
*
164
163
* @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key)
165
164
*/
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 = {
167
166
val m = GCAS_READ (ct) // use -Yinline!
168
167
169
168
m match {
@@ -220,7 +219,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
220
219
case otherv => None
221
220
}
222
221
case sn : TNode [K , V ] =>
223
- clean(parent, ct, lev - 5 )
222
+ clean(parent.nn , ct, lev - 5 )
224
223
null
225
224
case ln : LNode [K , V ] => // 3) an l-node
226
225
def insertln () = {
@@ -259,7 +258,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
259
258
* @return NO_SUCH_ELEMENT_SENTINEL if no value has been found, RESTART if the operation wasn't successful,
260
259
* or any other value otherwise
261
260
*/
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 = {
263
262
val m = GCAS_READ (ct) // use -Yinline!
264
263
265
264
m match {
@@ -286,7 +285,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
286
285
}
287
286
case tn : TNode [_, _] => // 3) non-live node
288
287
def cleanReadOnly (tn : TNode [K , V ]) = if (ct.nonReadOnly) {
289
- clean(parent, ct, lev - 5 )
288
+ clean(parent.nn , ct, lev - 5 )
290
289
RESTART
291
290
} else {
292
291
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
314
313
removalPolicy : Int ,
315
314
hc : Int ,
316
315
lev : Int ,
317
- parent : INode [K , V ],
316
+ parent : INode [K , V ] | Null ,
318
317
startgen : Gen ,
319
- ct : TrieMap [K , V ]): Option [V ] = {
318
+ ct : TrieMap [K , V ]): Option [V ] | Null = {
320
319
321
320
GCAS_READ (ct) match {
322
321
case cn : CNode [K , V ] =>
@@ -344,8 +343,8 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
344
343
345
344
if (res == None || (res eq null )) res
346
345
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)
349
348
cn match {
350
349
case cn : CNode [K , V ] =>
351
350
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
358
357
if (sub eq this ) (nonlive : @ uc) match {
359
358
case tn : TNode [K , V ] @ uc =>
360
359
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))
362
361
if (ct.readRoot().gen == startgen) cleanParent(nonlive)
363
362
}
364
363
}
@@ -376,7 +375,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
376
375
}
377
376
}
378
377
case tn : TNode [K , V ] =>
379
- clean(parent, ct, lev - 5 )
378
+ clean(parent.nn , ct, lev - 5 )
380
379
null
381
380
case ln : LNode [K , V ] =>
382
381
if (removalPolicy == RemovalPolicy .Always ) {
@@ -404,10 +403,10 @@ private[collection] final class INode[K, V](bn: MainNode[K, V] | Null, g: Gen, e
404
403
def isNullInode (ct : TrieMap [K , V ]) = GCAS_READ (ct) eq null
405
404
406
405
def cachedSize (ct : TrieMap [K , V ]): Int =
407
- GCAS_READ (ct).cachedSize(ct)
406
+ GCAS_READ (ct).nn. cachedSize(ct)
408
407
409
408
def knownSize (ct : TrieMap [K , V ]): Int =
410
- GCAS_READ (ct).knownSize()
409
+ GCAS_READ (ct).nn. knownSize()
411
410
412
411
/* this is a quiescent method! */
413
412
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
690
689
* For details, see: [[http://lampwww.epfl.ch/~prokopec/ctries-snapshot.pdf ]]
691
690
*/
692
691
@ 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 ])
694
693
extends scala.collection.mutable.AbstractMap [K , V ]
695
694
with scala.collection.concurrent.Map [K , V ]
696
695
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
788
787
}
789
788
}
790
789
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)
793
792
if (CAS_ROOT (ov, desc)) {
794
793
RDCSS_Complete (abort = false )
795
794
/* READ*/ desc.committed
0 commit comments