Skip to content

Commit 4fe5ed5

Browse files
committed
Modify two to enhance sharing
Previously, we passed `two` two unpacked key-value pairs: `hx`, `kx`, `vx`, `hy`, `ky`, `vy`. But at every call site, we already have `Leaf hy (L ky vy)`. So instead of building a new copy of the leaf, we can just pass the one we have to `two`.
1 parent ec84ad5 commit 4fe5ed5

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

Data/HashMap/Base.hs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ insert' h0 k0 v0 m0 = go h0 k0 v0 0 m0
675675
then t
676676
else Leaf h (L k x)
677677
else collision h l (L k x)
678-
| otherwise = runST (two s h k x hy ky y)
678+
| otherwise = runST (two s h k x hy t)
679679
go h k x s t@(BitmapIndexed b ary)
680680
| b .&. m == 0 =
681681
let !ary' = A.insert ary i $! Leaf h (L k x)
@@ -711,9 +711,9 @@ insertNewKey :: Hash -> k -> v -> HashMap k v -> HashMap k v
711711
insertNewKey !h0 !k0 x0 !m0 = go h0 k0 x0 0 m0
712712
where
713713
go !h !k x !_ Empty = Leaf h (L k x)
714-
go h k x s (Leaf hy l@(L ky y))
714+
go h k x s t@(Leaf hy l)
715715
| hy == h = collision h l (L k x)
716-
| otherwise = runST (two s h k x hy ky y)
716+
| otherwise = runST (two s h k x hy t)
717717
go h k x s (BitmapIndexed b ary)
718718
| b .&. m == 0 =
719719
let !ary' = A.insert ary i $! Leaf h (L k x)
@@ -800,7 +800,7 @@ unsafeInsert k0 v0 m0 = runST (go h0 k0 v0 0 m0)
800800
then return t
801801
else return $! Leaf h (L k x)
802802
else return $! collision h l (L k x)
803-
| otherwise = two s h k x hy ky y
803+
| otherwise = two s h k x hy t
804804
go h k x s t@(BitmapIndexed b ary)
805805
| b .&. m == 0 = do
806806
ary' <- A.insertM ary i $! Leaf h (L k x)
@@ -823,18 +823,20 @@ unsafeInsert k0 v0 m0 = runST (go h0 k0 v0 0 m0)
823823
| otherwise = go h k x s $ BitmapIndexed (mask hy s) (A.singleton t)
824824
{-# INLINABLE unsafeInsert #-}
825825

826-
-- | Create a map from two key-value pairs which hashes don't collide.
827-
two :: Shift -> Hash -> k -> v -> Hash -> k -> v -> ST s (HashMap k v)
826+
-- | Create a map from two key-value pairs which hashes don't collide. To
827+
-- enhance sharing, the second key-value pair is represented by the hash of its
828+
-- key and a singleton HashMap pairing its key with its value.
829+
two :: Shift -> Hash -> k -> v -> Hash -> HashMap k v -> ST s (HashMap k v)
828830
two = go
829831
where
830-
go s h1 k1 v1 h2 k2 v2
832+
go s h1 k1 v1 h2 t2
831833
| bp1 == bp2 = do
832-
st <- go (s+bitsPerSubkey) h1 k1 v1 h2 k2 v2
834+
st <- go (s+bitsPerSubkey) h1 k1 v1 h2 t2
833835
ary <- A.singletonM st
834836
return $ BitmapIndexed bp1 ary
835837
| otherwise = do
836838
mary <- A.new 2 $! Leaf h1 (L k1 v1)
837-
A.write mary idx2 $! Leaf h2 (L k2 v2)
839+
A.write mary idx2 $! t2
838840
ary <- A.unsafeFreeze mary
839841
return $! BitmapIndexed (bp1 .|. bp2) ary
840842
where
@@ -875,7 +877,7 @@ insertModifying x f k0 m0 = go h0 k0 0 m0
875877
(# v' #) | ptrEq y v' -> t
876878
| otherwise -> Leaf h (L k (v'))
877879
else collision h l (L k x)
878-
| otherwise = runST (two s h k x hy ky y)
880+
| otherwise = runST (two s h k x hy t)
879881
go h k s t@(BitmapIndexed b ary)
880882
| b .&. m == 0 =
881883
let ary' = A.insert ary i $! Leaf h (L k x)
@@ -935,11 +937,11 @@ unsafeInsertWith f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
935937
h0 = hash k0
936938
go :: Hash -> k -> v -> Shift -> HashMap k v -> ST s (HashMap k v)
937939
go !h !k x !_ Empty = return $! Leaf h (L k x)
938-
go h k x s (Leaf hy l@(L ky y))
940+
go h k x s t@(Leaf hy l@(L ky y))
939941
| hy == h = if ky == k
940942
then return $! Leaf h (L k (f x y))
941943
else return $! collision h l (L k x)
942-
| otherwise = two s h k x hy ky y
944+
| otherwise = two s h k x hy t
943945
go h k x s t@(BitmapIndexed b ary)
944946
| b .&. m == 0 = do
945947
ary' <- A.insertM ary i $! Leaf h (L k x)

Data/HashMap/Strict/Base.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ insertWith f k0 v0 m0 = go h0 k0 v0 0 m0
152152
where
153153
h0 = hash k0
154154
go !h !k x !_ Empty = leaf h k x
155-
go h k x s (Leaf hy l@(L ky y))
155+
go h k x s t@(Leaf hy l@(L ky y))
156156
| hy == h = if ky == k
157157
then leaf h k (f x y)
158158
else x `seq` (collision h l (L k x))
159-
| otherwise = x `seq` runST (two s h k x hy ky y)
159+
| otherwise = x `seq` runST (two s h k x hy t)
160160
go h k x s (BitmapIndexed b ary)
161161
| b .&. m == 0 =
162162
let ary' = A.insert ary i $! leaf h k x
@@ -186,13 +186,13 @@ unsafeInsertWith f k0 v0 m0 = runST (go h0 k0 v0 0 m0)
186186
where
187187
h0 = hash k0
188188
go !h !k x !_ Empty = return $! leaf h k x
189-
go h k x s (Leaf hy l@(L ky y))
189+
go h k x s t@(Leaf hy l@(L ky y))
190190
| hy == h = if ky == k
191191
then return $! leaf h k (f x y)
192192
else do
193193
let l' = x `seq` (L k x)
194194
return $! collision h l l'
195-
| otherwise = x `seq` two s h k x hy ky y
195+
| otherwise = x `seq` two s h k x hy t
196196
go h k x s t@(BitmapIndexed b ary)
197197
| b .&. m == 0 = do
198198
ary' <- A.insertM ary i $! leaf h k x

0 commit comments

Comments
 (0)