@@ -527,6 +527,10 @@ insert k0 v0 m0 = go h0 k0 v0 0 m0
527
527
| otherwise = go h k x s $ BitmapIndexed (mask hy s) (A. singleton t)
528
528
{-# INLINABLE insert #-}
529
529
530
+ -- | /O(log n)/ Associate the specified value with the specified
531
+ -- key in this map. If this map previously contained a mapping for
532
+ -- the key, the old value is replaced. Returns a tuple containing the
533
+ -- hashmap's change in size, and the hashmap after the insertion.
530
534
insertInternal :: (Eq k , Hashable k ) => k -> v -> HashMap k v -> (Int , HashMap k v )
531
535
insertInternal k0 v0 m0 = go h0 k0 v0 0 m0
532
536
where
@@ -602,6 +606,48 @@ unsafeInsert k0 v0 m0 = runST (go h0 k0 v0 0 m0)
602
606
| otherwise = go h k x s $ BitmapIndexed (mask hy s) (A. singleton t)
603
607
{-# INLINABLE unsafeInsert #-}
604
608
609
+ -- | In-place update version of insert. Returns a tuple with the
610
+ -- HashMap's change in size and the hashmap itself.
611
+ unsafeInsertInternal :: (Eq k , Hashable k ) => k -> v -> HashMap k v -> (Int , HashMap k v )
612
+ unsafeInsertInternal k0 v0 m0 = runST (go h0 k0 v0 0 m0)
613
+ where
614
+ h0 = hash k0
615
+ go ! h ! k x ! _ Empty = return $! (1 , Leaf h (L k x))
616
+ go h k x s t@ (Leaf hy l@ (L ky y))
617
+ | hy == h = if ky == k
618
+ then if x `ptrEq` y
619
+ then return (0 , t)
620
+ else return $! (0 , Leaf h (L k x))
621
+ else return $! (1 , collision h l (L k x))
622
+ | otherwise = do
623
+ twoHm <- two s h k x hy ky y
624
+ return $! (1 , twoHm)
625
+ go h k x s t@ (BitmapIndexed b ary)
626
+ | b .&. m == 0 = do
627
+ ary' <- A. insertM ary i $! Leaf h (L k x)
628
+ return $! (1 , bitmapIndexedOrFull (b .|. m) ary')
629
+ | otherwise = do
630
+ st <- A. indexM ary i
631
+ (sz, st') <- go h k x (s+ bitsPerSubkey) st
632
+ A. unsafeUpdateM ary i st'
633
+ return (sz, t)
634
+ where m = mask h s
635
+ i = sparseIndex b m
636
+ go h k x s t@ (Full ary) = do
637
+ st <- A. indexM ary i
638
+ (sz, st') <- go h k x (s+ bitsPerSubkey) st
639
+ A. unsafeUpdateM ary i st'
640
+ return (sz, t)
641
+ where i = index h s
642
+ go h k x s t@ (Collision hy v)
643
+ | h == hy =
644
+ let ! start = A. length v
645
+ ! newV = updateOrSnocWith const k x v
646
+ ! end = A. length newV
647
+ in return $! (end - start, Collision h newV)
648
+ | otherwise = go h k x s $ BitmapIndexed (mask hy s) (A. singleton t)
649
+ {-# INLINABLE unsafeInsertInternal #-}
650
+
605
651
-- | Create a map from two key-value pairs which hashes don't collide.
606
652
two :: Shift -> Hash -> k -> v -> Hash -> k -> v -> ST s (HashMap k v )
607
653
two = go
0 commit comments