File tree 2 files changed +17
-3
lines changed
2 files changed +17
-3
lines changed Original file line number Diff line number Diff line change @@ -128,6 +128,7 @@ module Data.HashMap.Internal
128
128
, equalKeys1
129
129
, lookupRecordCollision
130
130
, LookupRes (.. )
131
+ , lookupResToMaybe
131
132
, insert'
132
133
, delete'
133
134
, lookup'
@@ -613,6 +614,10 @@ lookup' h k m = case lookupRecordCollision# h k m of
613
614
-- If a collision did not occur then it will have the Int value (-1).
614
615
data LookupRes a = Absent | Present a ! Int
615
616
617
+ lookupResToMaybe :: LookupRes a -> Maybe a
618
+ lookupResToMaybe Absent = Nothing
619
+ lookupResToMaybe (Present x _) = Just x
620
+
616
621
-- Internal helper for lookup. This version takes the precomputed hash so
617
622
-- that functions that make multiple calls to lookup and related functions
618
623
-- (insert, delete) only need to calculate the hash once.
Original file line number Diff line number Diff line change @@ -305,9 +305,18 @@ update f = alter (>>= f)
305
305
-- @
306
306
alter :: (Eq k , Hashable k ) => (Maybe v -> Maybe v ) -> k -> HashMap k v -> HashMap k v
307
307
alter f k m =
308
- case f (HM. lookup k m) of
309
- Nothing -> HM. delete k m
310
- Just v -> insert k v m
308
+ let ! h = hash k
309
+ ! lookupRes = HM. lookupRecordCollision h k m
310
+ in case f (HM. lookupResToMaybe lookupRes) of
311
+ Nothing -> case lookupRes of
312
+ Absent -> m
313
+ Present _ collPos -> HM. deleteKeyExists collPos h k m
314
+ Just ! v' -> case lookupRes of
315
+ Absent -> HM. insertNewKey h k v' m
316
+ Present ! v collPos ->
317
+ if v `ptrEq` v'
318
+ then m
319
+ else HM. insertKeyExists collPos h k v' m
311
320
{-# INLINABLE alter #-}
312
321
313
322
-- | /O(log n)/ The expression (@'alterF' f k map@) alters the value @x@ at
You can’t perform that action at this time.
0 commit comments