1313import java .io .Serializable ;
1414import java .util .*;
1515import java .util .concurrent .Callable ;
16- import java .util .concurrent .atomic .AtomicBoolean ;
16+ import java .util .concurrent .atomic .AtomicReference ;
1717
1818/*
1919 A persistent rendition of Phil Bagwell's Hash Array Mapped Trie
@@ -238,7 +238,7 @@ public IPersistentMap meta(){
238238}
239239
240240static final class TransientHashMap extends ATransientMap {
241- AtomicBoolean edit ;
241+ AtomicReference < Thread > edit ;
242242 INode root ;
243243 int count ;
244244 boolean hasNull ;
@@ -247,10 +247,10 @@ static final class TransientHashMap extends ATransientMap {
247247
248248
249249 TransientHashMap (PersistentHashMap m ) {
250- this (new AtomicBoolean ( true ), m .root , m .count , m .hasNull , m .nullValue );
250+ this (new AtomicReference < Thread >( Thread . currentThread () ), m .root , m .count , m .hasNull , m .nullValue );
251251 }
252252
253- TransientHashMap (AtomicBoolean edit , INode root , int count , boolean hasNull , Object nullValue ) {
253+ TransientHashMap (AtomicReference < Thread > edit , INode root , int count , boolean hasNull , Object nullValue ) {
254254 this .edit = edit ;
255255 this .root = root ;
256256 this .count = count ;
@@ -297,7 +297,7 @@ ITransientMap doWithout(Object key) {
297297 }
298298
299299 IPersistentMap doPersistent () {
300- edit .set (false );
300+ edit .set (null );
301301 return new PersistentHashMap (count , root , hasNull , nullValue );
302302 }
303303
@@ -317,9 +317,8 @@ int doCount() {
317317 }
318318
319319 void ensureEditable (){
320- if (edit .get ())
321- return ;
322- throw new IllegalAccessError ("Transient used after persistent! call" );
320+ if (edit .get () == null )
321+ throw new IllegalAccessError ("Transient used after persistent! call" );
323322 }
324323}
325324
@@ -334,9 +333,9 @@ static interface INode extends Serializable {
334333
335334 ISeq nodeSeq ();
336335
337- INode assoc (AtomicBoolean edit , int shift , int hash , Object key , Object val , Box addedLeaf );
336+ INode assoc (AtomicReference < Thread > edit , int shift , int hash , Object key , Object val , Box addedLeaf );
338337
339- INode without (AtomicBoolean edit , int shift , int hash , Object key , Box removedLeaf );
338+ INode without (AtomicReference < Thread > edit , int shift , int hash , Object key , Box removedLeaf );
340339
341340 public Object kvreduce (IFn f , Object init );
342341
@@ -346,9 +345,9 @@ static interface INode extends Serializable {
346345final static class ArrayNode implements INode {
347346 int count ;
348347 final INode [] array ;
349- final AtomicBoolean edit ;
348+ final AtomicReference < Thread > edit ;
350349
351- ArrayNode (AtomicBoolean edit , int count , INode [] array ){
350+ ArrayNode (AtomicReference < Thread > edit , int count , INode [] array ){
352351 this .array = array ;
353352 this .edit = edit ;
354353 this .count = count ;
@@ -459,20 +458,20 @@ public Object call() throws Exception{
459458 }
460459
461460
462- private ArrayNode ensureEditable (AtomicBoolean edit ){
461+ private ArrayNode ensureEditable (AtomicReference < Thread > edit ){
463462 if (this .edit == edit )
464463 return this ;
465464 return new ArrayNode (edit , count , this .array .clone ());
466465 }
467466
468- private ArrayNode editAndSet (AtomicBoolean edit , int i , INode n ){
467+ private ArrayNode editAndSet (AtomicReference < Thread > edit , int i , INode n ){
469468 ArrayNode editable = ensureEditable (edit );
470469 editable .array [i ] = n ;
471470 return editable ;
472471 }
473472
474473
475- private INode pack (AtomicBoolean edit , int idx ) {
474+ private INode pack (AtomicReference < Thread > edit , int idx ) {
476475 Object [] newArray = new Object [2 *(count - 1 )];
477476 int j = 1 ;
478477 int bitmap = 0 ;
@@ -491,7 +490,7 @@ private INode pack(AtomicBoolean edit, int idx) {
491490 return new BitmapIndexedNode (edit , bitmap , newArray );
492491 }
493492
494- public INode assoc (AtomicBoolean edit , int shift , int hash , Object key , Object val , Box addedLeaf ){
493+ public INode assoc (AtomicReference < Thread > edit , int shift , int hash , Object key , Object val , Box addedLeaf ){
495494 int idx = mask (hash , shift );
496495 INode node = array [idx ];
497496 if (node == null ) {
@@ -505,7 +504,7 @@ public INode assoc(AtomicBoolean edit, int shift, int hash, Object key, Object v
505504 return editAndSet (edit , idx , n );
506505 }
507506
508- public INode without (AtomicBoolean edit , int shift , int hash , Object key , Box removedLeaf ){
507+ public INode without (AtomicReference < Thread > edit , int shift , int hash , Object key , Box removedLeaf ){
509508 int idx = mask (hash , shift );
510509 INode node = array [idx ];
511510 if (node == null )
@@ -571,13 +570,13 @@ final static class BitmapIndexedNode implements INode{
571570
572571 int bitmap ;
573572 Object [] array ;
574- final AtomicBoolean edit ;
573+ final AtomicReference < Thread > edit ;
575574
576575 final int index (int bit ){
577576 return Integer .bitCount (bitmap & (bit - 1 ));
578577 }
579578
580- BitmapIndexedNode (AtomicBoolean edit , int bitmap , Object [] array ){
579+ BitmapIndexedNode (AtomicReference < Thread > edit , int bitmap , Object [] array ){
581580 this .bitmap = bitmap ;
582581 this .array = array ;
583582 this .edit = edit ;
@@ -696,7 +695,7 @@ public Object fold(IFn combinef, IFn reducef, IFn fjtask, IFn fjfork, IFn fjjoin
696695 return NodeSeq .kvreduce (array , reducef , combinef .invoke ());
697696 }
698697
699- private BitmapIndexedNode ensureEditable (AtomicBoolean edit ){
698+ private BitmapIndexedNode ensureEditable (AtomicReference < Thread > edit ){
700699 if (this .edit == edit )
701700 return this ;
702701 int n = Integer .bitCount (bitmap );
@@ -705,20 +704,20 @@ private BitmapIndexedNode ensureEditable(AtomicBoolean edit){
705704 return new BitmapIndexedNode (edit , bitmap , newArray );
706705 }
707706
708- private BitmapIndexedNode editAndSet (AtomicBoolean edit , int i , Object a ) {
707+ private BitmapIndexedNode editAndSet (AtomicReference < Thread > edit , int i , Object a ) {
709708 BitmapIndexedNode editable = ensureEditable (edit );
710709 editable .array [i ] = a ;
711710 return editable ;
712711 }
713712
714- private BitmapIndexedNode editAndSet (AtomicBoolean edit , int i , Object a , int j , Object b ) {
713+ private BitmapIndexedNode editAndSet (AtomicReference < Thread > edit , int i , Object a , int j , Object b ) {
715714 BitmapIndexedNode editable = ensureEditable (edit );
716715 editable .array [i ] = a ;
717716 editable .array [j ] = b ;
718717 return editable ;
719718 }
720719
721- private BitmapIndexedNode editAndRemovePair (AtomicBoolean edit , int bit , int i ) {
720+ private BitmapIndexedNode editAndRemovePair (AtomicReference < Thread > edit , int bit , int i ) {
722721 if (bitmap == bit )
723722 return null ;
724723 BitmapIndexedNode editable = ensureEditable (edit );
@@ -729,7 +728,7 @@ private BitmapIndexedNode editAndRemovePair(AtomicBoolean edit, int bit, int i)
729728 return editable ;
730729 }
731730
732- public INode assoc (AtomicBoolean edit , int shift , int hash , Object key , Object val , Box addedLeaf ){
731+ public INode assoc (AtomicReference < Thread > edit , int shift , int hash , Object key , Object val , Box addedLeaf ){
733732 int bit = bitpos (hash , shift );
734733 int idx = index (bit );
735734 if ((bitmap & bit ) != 0 ) {
@@ -789,7 +788,7 @@ public INode assoc(AtomicBoolean edit, int shift, int hash, Object key, Object v
789788 }
790789 }
791790
792- public INode without (AtomicBoolean edit , int shift , int hash , Object key , Box removedLeaf ){
791+ public INode without (AtomicReference < Thread > edit , int shift , int hash , Object key , Box removedLeaf ){
793792 int bit = bitpos (hash , shift );
794793 if ((bitmap & bit ) == 0 )
795794 return this ;
@@ -820,9 +819,9 @@ final static class HashCollisionNode implements INode{
820819 final int hash ;
821820 int count ;
822821 Object [] array ;
823- final AtomicBoolean edit ;
822+ final AtomicReference < Thread > edit ;
824823
825- HashCollisionNode (AtomicBoolean edit , int hash , int count , Object ... array ){
824+ HashCollisionNode (AtomicReference < Thread > edit , int hash , int count , Object ... array ){
826825 this .edit = edit ;
827826 this .hash = hash ;
828827 this .count = count ;
@@ -897,15 +896,15 @@ public int findIndex(Object key){
897896 return -1 ;
898897 }
899898
900- private HashCollisionNode ensureEditable (AtomicBoolean edit ){
899+ private HashCollisionNode ensureEditable (AtomicReference < Thread > edit ){
901900 if (this .edit == edit )
902901 return this ;
903902 Object [] newArray = new Object [2 *(count +1 )]; // make room for next assoc
904903 System .arraycopy (array , 0 , newArray , 0 , 2 *count );
905904 return new HashCollisionNode (edit , hash , count , newArray );
906905 }
907906
908- private HashCollisionNode ensureEditable (AtomicBoolean edit , int count , Object [] array ){
907+ private HashCollisionNode ensureEditable (AtomicReference < Thread > edit , int count , Object [] array ){
909908 if (this .edit == edit ) {
910909 this .array = array ;
911910 this .count = count ;
@@ -914,21 +913,21 @@ private HashCollisionNode ensureEditable(AtomicBoolean edit, int count, Object[]
914913 return new HashCollisionNode (edit , hash , count , array );
915914 }
916915
917- private HashCollisionNode editAndSet (AtomicBoolean edit , int i , Object a ) {
916+ private HashCollisionNode editAndSet (AtomicReference < Thread > edit , int i , Object a ) {
918917 HashCollisionNode editable = ensureEditable (edit );
919918 editable .array [i ] = a ;
920919 return editable ;
921920 }
922921
923- private HashCollisionNode editAndSet (AtomicBoolean edit , int i , Object a , int j , Object b ) {
922+ private HashCollisionNode editAndSet (AtomicReference < Thread > edit , int i , Object a , int j , Object b ) {
924923 HashCollisionNode editable = ensureEditable (edit );
925924 editable .array [i ] = a ;
926925 editable .array [j ] = b ;
927926 return editable ;
928927 }
929928
930929
931- public INode assoc (AtomicBoolean edit , int shift , int hash , Object key , Object val , Box addedLeaf ){
930+ public INode assoc (AtomicReference < Thread > edit , int shift , int hash , Object key , Object val , Box addedLeaf ){
932931 if (hash == this .hash ) {
933932 int idx = findIndex (key );
934933 if (idx != -1 ) {
@@ -954,7 +953,7 @@ public INode assoc(AtomicBoolean edit, int shift, int hash, Object key, Object v
954953 .assoc (edit , shift , hash , key , val , addedLeaf );
955954 }
956955
957- public INode without (AtomicBoolean edit , int shift , int hash , Object key , Box removedLeaf ){
956+ public INode without (AtomicReference < Thread > edit , int shift , int hash , Object key , Box removedLeaf ){
958957 int idx = findIndex (key );
959958 if (idx == -1 )
960959 return this ;
@@ -1088,13 +1087,13 @@ private static INode createNode(int shift, Object key1, Object val1, int key2has
10881087 if (key1hash == key2hash )
10891088 return new HashCollisionNode (null , key1hash , 2 , new Object [] {key1 , val1 , key2 , val2 });
10901089 Box addedLeaf = new Box (null );
1091- AtomicBoolean edit = new AtomicBoolean ( false );
1090+ AtomicReference < Thread > edit = new AtomicReference < Thread >( );
10921091 return BitmapIndexedNode .EMPTY
10931092 .assoc (edit , shift , key1hash , key1 , val1 , addedLeaf )
10941093 .assoc (edit , shift , key2hash , key2 , val2 , addedLeaf );
10951094}
10961095
1097- private static INode createNode (AtomicBoolean edit , int shift , Object key1 , Object val1 , int key2hash , Object key2 , Object val2 ) {
1096+ private static INode createNode (AtomicReference < Thread > edit , int shift , Object key1 , Object val1 , int key2hash , Object key2 , Object val2 ) {
10981097 int key1hash = hash (key1 );
10991098 if (key1hash == key2hash )
11001099 return new HashCollisionNode (null , key1hash , 2 , new Object [] {key1 , val1 , key2 , val2 });
0 commit comments