@@ -127,9 +127,9 @@ module Data.HashMap.Internal
127
127
, sparseIndex
128
128
, two
129
129
, unionArrayBy
130
- , update32
131
- , update32M
132
- , update32With '
130
+ , updateFullArray
131
+ , updateFullArrayM
132
+ , updateFullArrayWith '
133
133
, updateOrConcatWithKey
134
134
, filterMapAux
135
135
, equalKeys
@@ -832,7 +832,7 @@ insert' h0 k0 v0 m0 = go h0 k0 v0 0 m0
832
832
! st' = go h k x (nextShift s) st
833
833
in if st' `ptrEq` st
834
834
then t
835
- else Full (update32 ary i st')
835
+ else Full (updateFullArray ary i st')
836
836
where i = index h s
837
837
go h k x s t@ (Collision hy v)
838
838
| h == hy = Collision h (updateOrSnocWith (\ a _ -> (# a # )) k x v)
@@ -866,7 +866,7 @@ insertNewKey !h0 !k0 x0 !m0 = go h0 k0 x0 0 m0
866
866
go h k x s (Full ary) =
867
867
let ! st = A. index ary i
868
868
! st' = go h k x (nextShift s) st
869
- in Full (update32 ary i st')
869
+ in Full (updateFullArray ary i st')
870
870
where i = index h s
871
871
go h k x s t@ (Collision hy v)
872
872
| h == hy = Collision h (A. snoc v (L k x))
@@ -895,7 +895,7 @@ insertKeyExists !collPos0 !h0 !k0 x0 !m0 = go collPos0 h0 k0 x0 m0
895
895
go collPos shiftedHash k x (Full ary) =
896
896
let ! st = A. index ary i
897
897
! st' = go collPos (shiftHash shiftedHash) k x st
898
- in Full (update32 ary i st')
898
+ in Full (updateFullArray ary i st')
899
899
where i = index' shiftedHash
900
900
go collPos _shiftedHash k x (Collision h v)
901
901
| collPos >= 0 = Collision h (setAtPosition collPos k x v)
@@ -1043,7 +1043,7 @@ insertModifying x f k0 m0 = go h0 k0 0 m0
1043
1043
go h k s t@ (Full ary) =
1044
1044
let ! st = A. index ary i
1045
1045
! st' = go h k (nextShift s) st
1046
- ary' = update32 ary i $! st'
1046
+ ary' = updateFullArray ary i $! st'
1047
1047
in if ptrEq st st'
1048
1048
then t
1049
1049
else Full ary'
@@ -1272,7 +1272,7 @@ adjust# f k0 m0 = go h0 k0 0 m0
1272
1272
let i = index h s
1273
1273
! st = A. index ary i
1274
1274
! st' = go h k (nextShift s) st
1275
- ary' = update32 ary i $! st'
1275
+ ary' = updateFullArray ary i $! st'
1276
1276
in if ptrEq st st'
1277
1277
then t
1278
1278
else Full ary'
@@ -1558,12 +1558,6 @@ submapBitmapIndexed comp !b1 !ary1 !b2 !ary2 = subsetBitmaps && go 0 0 (b1Orb2 .
1558
1558
go ! i ! j ! m
1559
1559
| m > b1Orb2 = True
1560
1560
1561
- #if WORD_SIZE_IN_BITS == 32
1562
- -- m can overflow to 0 on 32-bit platforms.
1563
- -- See #491.
1564
- | m == 0 = True
1565
- #endif
1566
-
1567
1561
-- In case a key is both in ary1 and ary2, check ary1[i] <= ary2[j] and
1568
1562
-- increment the indices i and j.
1569
1563
| b1Andb2 .&. m /= 0 = comp (A. index ary1 i) (A. index ary2 j) &&
@@ -1668,12 +1662,12 @@ unionWithKey f = go 0
1668
1662
go s (Full ary1) t2 =
1669
1663
let h2 = leafHashCode t2
1670
1664
i = index h2 s
1671
- ary' = update32With ' ary1 i $ \ st1 -> go (nextShift s) st1 t2
1665
+ ary' = updateFullArrayWith ' ary1 i $ \ st1 -> go (nextShift s) st1 t2
1672
1666
in Full ary'
1673
1667
go s t1 (Full ary2) =
1674
1668
let h1 = leafHashCode t1
1675
1669
i = index h1 s
1676
- ary' = update32With ' ary2 i $ \ st2 -> go (nextShift s) t1 st2
1670
+ ary' = updateFullArrayWith ' ary2 i $ \ st2 -> go (nextShift s) t1 st2
1677
1671
in Full ary'
1678
1672
1679
1673
leafHashCode (Leaf h _) = h
@@ -2414,24 +2408,24 @@ subsetArray cmpV ary1 ary2 = A.length ary1 <= A.length ary2 && A.all inAry2 ary1
2414
2408
-- Manually unrolled loops
2415
2409
2416
2410
-- | \(O(n)\) Update the element at the given position in this array.
2417
- update32 :: A. Array e -> Int -> e -> A. Array e
2418
- update32 ary idx b = runST (update32M ary idx b)
2419
- {-# INLINE update32 #-}
2411
+ updateFullArray :: A. Array e -> Int -> e -> A. Array e
2412
+ updateFullArray ary idx b = runST (updateFullArrayM ary idx b)
2413
+ {-# INLINE updateFullArray #-}
2420
2414
2421
2415
-- | \(O(n)\) Update the element at the given position in this array.
2422
- update32M :: A. Array e -> Int -> e -> ST s (A. Array e )
2423
- update32M ary idx b = do
2416
+ updateFullArrayM :: A. Array e -> Int -> e -> ST s (A. Array e )
2417
+ updateFullArrayM ary idx b = do
2424
2418
mary <- clone ary
2425
2419
A. write mary idx b
2426
2420
A. unsafeFreeze mary
2427
- {-# INLINE update32M #-}
2421
+ {-# INLINE updateFullArrayM #-}
2428
2422
2429
2423
-- | \(O(n)\) Update the element at the given position in this array, by applying a function to it.
2430
- update32With ' :: A. Array e -> Int -> (e -> e ) -> A. Array e
2431
- update32With ' ary idx f
2424
+ updateFullArrayWith ' :: A. Array e -> Int -> (e -> e ) -> A. Array e
2425
+ updateFullArrayWith ' ary idx f
2432
2426
| (# x # ) <- A. index# ary idx
2433
- = update32 ary idx $! f x
2434
- {-# INLINE update32With ' #-}
2427
+ = updateFullArray ary idx $! f x
2428
+ {-# INLINE updateFullArrayWith ' #-}
2435
2429
2436
2430
-- | Unsafely clone an array of (2^bitsPerSubkey) elements. The length of the input
2437
2431
-- array is not checked.
@@ -2448,8 +2442,16 @@ clone ary =
2448
2442
-- | Number of bits that are inspected at each level of the hash tree.
2449
2443
--
2450
2444
-- This constant is named /t/ in the original /Ideal Hash Trees/ paper.
2445
+ --
2446
+ -- Note that this constant is platform-dependent. On 32-bit platforms we use
2447
+ -- '4', because bitmaps using '2^5' bits turned out to be prone to integer
2448
+ -- overflow bugs. See #491 for instance.
2451
2449
bitsPerSubkey :: Int
2450
+ #if WORD_SIZE_IN_BITS < 64
2451
+ bitsPerSubkey = 4
2452
+ #else
2452
2453
bitsPerSubkey = 5
2454
+ #endif
2453
2455
2454
2456
-- | The size of a 'Full' node, i.e. @2 ^ 'bitsPerSubkey'@.
2455
2457
maxChildren :: Int
0 commit comments