Open
Description
These functions are currently sharing code with mapMaybe[WithKey]
via filterMapAux
.
unordered-containers/Data/HashMap/Internal.hs
Lines 2070 to 2137 in 19674b5
The inner step
loops currently work by reading from input Array
s and writing to new_
output MArray
s. If we were to give up the code sharing, the loops in filter[WithKey]
could perform both reads and writes on thaw
ed output MArray
s, removing the input arrays arguments from the inner loops, and possibly increasing cache locality.
For filterC
, this might look roughly like this:
@@ -2116,13 +2116,13 @@ filterMapAux onLeaf onColl = go
filterC ary0 h =
let !n = A.length ary0
in runST $ do
- mary <- A.new_ n
- step ary0 mary 0 0 n
+ mary <- A.thaw ary0 0 n
+ step mary 0 0 n
where
- step :: A.Array (Leaf k v1) -> A.MArray s (Leaf k v2)
+ step :: A.MArray s (Leaf k v2)
-> Int -> Int -> Int
-> ST s (HashMap k v2)
- step !ary !mary i !j n
+ step !mary i !j n
| i >= n = case j of
0 -> return Empty
1 -> do l <- A.read mary 0
@@ -2131,9 +2131,10 @@ filterMapAux onLeaf onColl = go
return $! Collision h ary2
| otherwise -> do ary2 <- A.unsafeFreeze =<< A.shrink mary j
return $! Collision h ary2
- | Just el <- onColl $! A.index ary i
- = A.write mary j el >> step ary mary (i+1) (j+1) n
- | otherwise = step ary mary (i+1) j n
+ | otherwise = do
+ case A.read mary i of
+ Just el -> A.write mary j el >> step mary (i+1) (j+1) n
+ Nothing -> step mary (i+1) j n
{-# INLINE filterMapAux #-}