@@ -157,6 +157,10 @@ data HashMap k v
157
157
158
158
type role HashMap nominal representational
159
159
160
+ -- | WIP. This will become the user-facing 'HashMap' after this PR is
161
+ -- finalized.
162
+ data HashMapW = HashMapW {- # UNPACK #-} !Int ! HashMap
163
+
160
164
instance (NFData k , NFData v ) => NFData (HashMap k v ) where
161
165
rnf Empty = ()
162
166
rnf (BitmapIndexed _ ary) = rnf ary
@@ -523,6 +527,46 @@ insert k0 v0 m0 = go h0 k0 v0 0 m0
523
527
| otherwise = go h k x s $ BitmapIndexed (mask hy s) (A. singleton t)
524
528
{-# INLINABLE insert #-}
525
529
530
+ insertInternal :: (Eq k , Hashable k ) => k -> v -> HashMap k v -> (Int , HashMap k v )
531
+ insertInternal k0 v0 m0 = go h0 k0 v0 0 m0
532
+ where
533
+ h0 = hash k0
534
+ go ! h ! k x ! _ Empty = (1 , Leaf h (L k x))
535
+ go h k x s t@ (Leaf hy l@ (L ky y))
536
+ | hy == h = if ky == k
537
+ then if x `ptrEq` y
538
+ then (0 , t)
539
+ else (0 , Leaf h (L k x))
540
+ else (1 , collision h l (L k x))
541
+ | otherwise = (1 , runST (two s h k x hy ky y))
542
+ go h k x s t@ (BitmapIndexed b ary)
543
+ | b .&. m == 0 =
544
+ let ! ary' = A. insert ary i $! Leaf h (L k x)
545
+ in (1 , bitmapIndexedOrFull (b .|. m) ary')
546
+ | otherwise =
547
+ let ! st = A. index ary i
548
+ (! sz, ! st') = go h k x (s+ bitsPerSubkey) st
549
+ in if st' `ptrEq` st
550
+ then (sz, t)
551
+ else (sz, BitmapIndexed b (A. update ary i st'))
552
+ where m = mask h s
553
+ i = sparseIndex b m
554
+ go h k x s t@ (Full ary) =
555
+ let ! st = A. index ary i
556
+ (! sz, ! st') = go h k x (s+ bitsPerSubkey) st
557
+ in if st' `ptrEq` st
558
+ then (sz, t)
559
+ else (sz, Full (update16 ary i st'))
560
+ where i = index h s
561
+ go h k x s t@ (Collision hy v)
562
+ | h == hy =
563
+ let ! start = A. length v
564
+ ! newV = updateOrSnocWith const k x v
565
+ ! end = A. length newV
566
+ in (end - start, Collision h newV)
567
+ | otherwise = go h k x s $ BitmapIndexed (mask hy s) (A. singleton t)
568
+ {-# INLINABLE insertInternal #-}
569
+
526
570
-- | In-place update version of insert
527
571
unsafeInsert :: (Eq k , Hashable k ) => k -> v -> HashMap k v -> HashMap k v
528
572
unsafeInsert k0 v0 m0 = runST (go h0 k0 v0 0 m0)
@@ -1342,7 +1386,7 @@ fullNodeMask :: Bitmap
1342
1386
fullNodeMask = complement (complement 0 `unsafeShiftL` maxChildren)
1343
1387
{-# INLINE fullNodeMask #-}
1344
1388
1345
- -- | Check if two the two arguments are the same value. N.B. This
1389
+ -- | Check if the two arguments are the same value. N.B. This
1346
1390
-- function might give false negatives (due to GC moving objects.)
1347
1391
ptrEq :: a -> a -> Bool
1348
1392
ptrEq x y = isTrue# (reallyUnsafePtrEquality# x y ==# 1 # )
0 commit comments