packages feed

ecta-1.0.0.0: src/Data/Interned/Extended/SingleThreaded.hs

module Data.Interned.Extended.SingleThreaded (
    intern
  ) where


import Data.Array
import Data.Hashable
import qualified Data.HashMap.Strict as HashMap
import Data.IORef
import GHC.IO (unsafeDupablePerformIO)

import Data.Interned.Internal hiding ( intern )

--------------------------------------------------

intern :: Interned t => Uninterned t -> t
intern !bt = unsafeDupablePerformIO $ modifyAdvice $ do
    CacheState i m <- readIORef slot
    case HashMap.lookup dt m of
      Nothing -> do let t = identify (wid * i + r) bt
                    writeIORef slot (CacheState (i + 1) (HashMap.insert dt t m))
                    return t
      Just t  -> return t
  where
  slot = getCache cache ! r
  !dt = describe bt
  !hdt = hash dt
  !wid = cacheWidth dt
  r = hdt `mod` wid