packages feed

HMap 1.1.5 → 1.1.6

raw patch · 3 files changed

+45/−9 lines, 3 files

Files

ChangeLog view
@@ -1,3 +1,5 @@+1.1.6: Better memory performance: An entry into an HMap does not keep the value alive if the key is not alive. After all, if the key is dead, then there is no way to retrieve the value! Also added IO operation purge to remove dead elements.+ 1.1.5: Added operation to split a KeyT monad. Super trippyness!  1.1.4: Forgot to export KeyT
Data/HMap.hs view
@@ -96,7 +96,14 @@ -- * This module uses a Hashmap as a backend, whereas @stable-maps@ uses @Data.Map@. --   Hashmaps are faster, see <http://blog.johantibell.com/2012/03/announcing-unordered-containers-02.html>. --+-- Another difference to both packages is that HMap has better memory performance +-- in the following way: An entry into an HMap does not keep+-- the value alive if the key is not alive. After all, if the key+-- is dead, then there is no way to retrieve the value! --+-- Hence, a HMap can have elements which can never be accessed +-- again. Use the IO operation 'purge' to remove these.+-- -- Since many function names (but not the type name) clash with -- "Prelude" names, this module is usually imported @qualified@, e.g. --@@ -174,8 +181,9 @@   import qualified Data.HashMap.Lazy as M-import Data.Maybe(fromJust)-+import Data.Maybe(fromJust,isJust)+import System.Mem.Weak+import System.IO.Unsafe   {--------------------------------------------------------------------@@ -185,7 +193,7 @@   -- | The type of hetrogenous maps. -newtype HMap = HMap (HashMap Unique HideType) +newtype HMap = HMap (HashMap Unique (Weak HideType))    @@ -234,7 +242,15 @@ -- or 'Nothing' if the key isn't in the map.  lookup :: HKey x a -> HMap -> Maybe a-lookup (Key x) (HMap m) = fmap unsafeFromHideType (M.lookup x m)+lookup (Key k) (HMap m) =  fmap getVal (M.lookup k m) where+  -- we know it is alive, how else did we get the key?+  getVal v = (keepAlive k unsafeFromHideType) -- keep key alive till unsafeFromHideType +             (unsafePerformIO (liftM fromJust (deRefWeak v)))++  -- this function keeps the key k alive until computing whnf of application of f to x+  keepAlive :: a -> (b -> c) -> (b -> c)+  keepAlive k f x = k `seq` (f x)+  {-# NOINLINE keepAlive #-}   #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE lookup #-} #else@@ -293,7 +309,7 @@   singleton :: HKey x a -> a -> HMap-singleton (Key k) x = HMap (M.singleton k (HideType x))+singleton k x = insert k x empty {-# INLINE singleton #-}  @@ -304,9 +320,12 @@ -- If the key is already present in the map, the associated value is -- replaced with the supplied value. 'insert' is equivalent to -- @'insertWith' 'const'@.+insert :: HKey s a -> a -> HMap -> HMap+insert (Key k) a (HMap m) = let v = unsafeMKWeak k (HideType a)+                            in v `seq` HMap (M.insert k v m)  -insert :: HKey x a -> a -> HMap -> HMap-insert (Key k) a (HMap m) = HMap (M.insert k (HideType a) m)+{- NOINLINE unsafeMKWeak -}+unsafeMKWeak k a = unsafePerformIO $ mkWeak k a Nothing #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE insert #-} #else@@ -437,7 +456,22 @@ {-# INLINABLE intersection #-} #endif -+{--------------------------------------------------------------------+  Garbage collection.+--------------------------------------------------------------------}+-- | /O(n)/. Remove dead values from map.+--+-- An entry into an HMap does not keep the value alive +-- if the key is not alive. After all, if the key+-- is dead, then there is no way to retrieve the value!+--+-- Hence, a HMap can have elements which can never be accessed +-- again. This operation purges such elements from the given+-- map. Notice that this does change the size of the map+-- and is hence in the IO monad.  +purge :: HMap -> IO HMap+purge (HMap m) = liftM (HMap . M.fromList) $ filterM isAlive (M.toList m) +  where isAlive (k,v) = liftM isJust $ deRefWeak v  
HMap.cabal view
@@ -1,5 +1,5 @@ Name:                HMap-Version:             1.1.5+Version:             1.1.6 Synopsis:	     Fast heterogeneous maps and unconstrained typeable like functionality. Description:         Fast heterogeneous maps based on Hashmaps  and type-able like functionality for type that are not typeable. License:             BSD3