52
52
*
53
53
* It may make sense to use a sealed interface here eventually, rather than dispatching manually
54
54
* with instanceof.
55
- *
56
- * Care must be taken when using right shift (>>), as it sign-extends, It is generally needed to use
57
- * bitmasking, unlike in the cpython implementation/original paper
58
55
*/
59
56
60
57
public final class Hamt {
@@ -102,8 +99,7 @@ private Hamt(TreePart root) {
102
99
}
103
100
104
101
private static int hashIdx (int hash , int hashShift ) {
105
- // since we never access the bits the shift adds here, it is fine that it is adding ones to
106
- // the start
102
+ // Since we mask off the high 2 bits of the hash, it is always positive
107
103
return hashTail (hash >> hashShift );
108
104
}
109
105
@@ -121,9 +117,9 @@ private static int popcount(int n) {
121
117
}
122
118
123
119
private static int bitmapToIdx (int bitmap , int position ) {
124
- if (( bitmap & ( 1 << position )) != 0 ) {
125
- // java cannot do unsigned shifts, so we need to mask off the low bits instead
126
- return popcount (bitmap & (- 1 << position ) ) - 1 ;
120
+ int shiftedBitmap = bitmap >>> position ;
121
+ if (( shiftedBitmap & 1 ) == 1 ) {
122
+ return popcount (shiftedBitmap ) - 1 ;
127
123
} else {
128
124
return -1 ;
129
125
}
@@ -166,7 +162,7 @@ private static TreePart partWithEntry(TreePart original, Entry newEntry, int has
166
162
newElems [position ] = newEntry ;
167
163
int elemsI = originalLength - 1 ;
168
164
for (int i = 0 ; i < 32 ; ++i ) {
169
- if (((existing .bitmap ) & ( 1 << i )) != 0 ) {
165
+ if (((existing .bitmap >>> i ) & 1 ) == 1 ) {
170
166
newElems [i ] = existing .elems [elemsI --];
171
167
}
172
168
}
0 commit comments