{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE ExplicitForAll #-}
module Data.HashTable.IO
( BasicHashTable
, CuckooHashTable
, LinearHashTable
, IOHashTable
, new
, newSized
, insert
, delete
, lookup
, mutate
, mutateIO
, fromList
, fromListWithSizeHint
, toList
, mapM_
, foldM
, computeOverhead
, lookupIndex
, nextByIndex
) where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative
import Data.Word
#endif
import Control.Monad.Primitive (PrimState)
import Control.Monad.ST (stToIO)
import Data.Hashable (Hashable)
import qualified Data.HashTable.Class as C
import GHC.IO (ioToST)
import Prelude hiding (lookup, mapM_)
import Data.HashTable.Internal.Utils (unsafeIOToST)
import qualified Data.HashTable.ST.Basic as B
import qualified Data.HashTable.ST.Cuckoo as Cu
import qualified Data.HashTable.ST.Linear as L
type BasicHashTable k v = IOHashTable (B.HashTable) k v
type CuckooHashTable k v = IOHashTable (Cu.HashTable) k v
type LinearHashTable k v = IOHashTable (L.HashTable) k v
type IOHashTable tabletype k v = tabletype (PrimState IO) k v
new :: C.HashTable h => IO (IOHashTable h k v)
new = stToIO C.new
{-# INLINE new #-}
{-# SPECIALIZE INLINE new :: IO (BasicHashTable k v) #-}
{-# SPECIALIZE INLINE new :: IO (LinearHashTable k v) #-}
{-# SPECIALIZE INLINE new :: IO (CuckooHashTable k v) #-}
newSized :: C.HashTable h => Int -> IO (IOHashTable h k v)
newSized = stToIO . C.newSized
{-# INLINE newSized #-}
{-# SPECIALIZE INLINE newSized :: Int -> IO (BasicHashTable k v) #-}
{-# SPECIALIZE INLINE newSized :: Int -> IO (LinearHashTable k v) #-}
{-# SPECIALIZE INLINE newSized :: Int -> IO (CuckooHashTable k v) #-}
insert :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> v -> IO ()
insert h k v = stToIO $ C.insert h k v
{-# INLINE insert #-}
{-# SPECIALIZE INLINE insert :: (Eq k, Hashable k) =>
BasicHashTable k v -> k -> v -> IO () #-}
{-# SPECIALIZE INLINE insert :: (Eq k, Hashable k) =>
LinearHashTable k v -> k -> v -> IO () #-}
{-# SPECIALIZE INLINE insert :: (Eq k, Hashable k) =>
CuckooHashTable k v -> k -> v -> IO () #-}
delete :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO ()
delete h k = stToIO $ C.delete h k
{-# INLINE delete #-}
{-# SPECIALIZE INLINE delete :: (Eq k, Hashable k) =>
BasicHashTable k v -> k -> IO () #-}
{-# SPECIALIZE INLINE delete :: (Eq k, Hashable k) =>
LinearHashTable k v -> k -> IO () #-}
{-# SPECIALIZE INLINE delete :: (Eq k, Hashable k) =>
CuckooHashTable k v -> k -> IO () #-}
lookup :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe v)
lookup h k = stToIO $ C.lookup h k
{-# INLINE lookup #-}
{-# SPECIALIZE INLINE lookup :: (Eq k, Hashable k) =>
BasicHashTable k v -> k -> IO (Maybe v) #-}
{-# SPECIALIZE INLINE lookup :: (Eq k, Hashable k) =>
LinearHashTable k v -> k -> IO (Maybe v) #-}
{-# SPECIALIZE INLINE lookup :: (Eq k, Hashable k) =>
CuckooHashTable k v -> k -> IO (Maybe v) #-}
lookupIndex :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> IO (Maybe Word)
lookupIndex h k = stToIO $ C.lookupIndex h k
{-# INLINE lookupIndex #-}
{-# SPECIALIZE INLINE lookupIndex :: (Eq k, Hashable k) =>
BasicHashTable k v -> k -> IO (Maybe Word) #-}
{-# SPECIALIZE INLINE lookupIndex :: (Eq k, Hashable k) =>
LinearHashTable k v -> k -> IO (Maybe Word) #-}
{-# SPECIALIZE INLINE lookupIndex :: (Eq k, Hashable k) =>
CuckooHashTable k v -> k -> IO (Maybe Word) #-}
nextByIndex :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> Word -> IO (Maybe (Word,k,v))
nextByIndex h k = stToIO $ C.nextByIndex h k
{-# INLINE nextByIndex #-}
{-# SPECIALIZE INLINE nextByIndex :: (Eq k, Hashable k) =>
BasicHashTable k v -> Word -> IO (Maybe (Word,k,v)) #-}
{-# SPECIALIZE INLINE nextByIndex :: (Eq k, Hashable k) =>
LinearHashTable k v -> Word -> IO (Maybe (Word,k,v)) #-}
{-# SPECIALIZE INLINE nextByIndex :: (Eq k, Hashable k) =>
CuckooHashTable k v -> Word -> IO (Maybe (Word,k,v)) #-}
mutateIO :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> (Maybe v -> IO (Maybe v, a)) -> IO a
mutateIO h k f = stToIO $ C.mutateST h k (ioToST . f)
{-# INLINE mutateIO #-}
{-# SPECIALIZE INLINE mutateIO :: (Eq k, Hashable k) =>
BasicHashTable k v -> k -> (Maybe v -> IO (Maybe v, a)) -> IO a #-}
{-# SPECIALIZE INLINE mutateIO :: (Eq k, Hashable k) =>
LinearHashTable k v -> k -> (Maybe v -> IO (Maybe v, a)) -> IO a #-}
{-# SPECIALIZE INLINE mutateIO :: (Eq k, Hashable k) =>
CuckooHashTable k v -> k -> (Maybe v -> IO (Maybe v, a)) -> IO a #-}
mutate :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> (Maybe v -> (Maybe v, a)) -> IO a
mutate h k f = stToIO $ C.mutate h k f
{-# INLINE mutate #-}
{-# SPECIALIZE INLINE mutate :: (Eq k, Hashable k) =>
BasicHashTable k v -> k -> (Maybe v -> (Maybe v, a)) -> IO a #-}
{-# SPECIALIZE INLINE mutate :: (Eq k, Hashable k) =>
LinearHashTable k v -> k -> (Maybe v -> (Maybe v, a)) -> IO a #-}
{-# SPECIALIZE INLINE mutate :: (Eq k, Hashable k) =>
CuckooHashTable k v -> k -> (Maybe v -> (Maybe v, a)) -> IO a #-}
fromList :: (C.HashTable h, Eq k, Hashable k) =>
[(k,v)] -> IO (IOHashTable h k v)
fromList = stToIO . C.fromList
{-# INLINE fromList #-}
{-# SPECIALIZE INLINE fromList :: (Eq k, Hashable k) =>
[(k,v)] -> IO (BasicHashTable k v) #-}
{-# SPECIALIZE INLINE fromList :: (Eq k, Hashable k) =>
[(k,v)] -> IO (LinearHashTable k v) #-}
{-# SPECIALIZE INLINE fromList :: (Eq k, Hashable k) =>
[(k,v)] -> IO (CuckooHashTable k v) #-}
fromListWithSizeHint :: (C.HashTable h, Eq k, Hashable k) =>
Int -> [(k,v)] -> IO (IOHashTable h k v)
fromListWithSizeHint n = stToIO . C.fromListWithSizeHint n
{-# INLINE fromListWithSizeHint #-}
{-# SPECIALIZE INLINE fromListWithSizeHint :: (Eq k, Hashable k) =>
Int -> [(k,v)] -> IO (BasicHashTable k v) #-}
{-# SPECIALIZE INLINE fromListWithSizeHint :: (Eq k, Hashable k) =>
Int -> [(k,v)] -> IO (LinearHashTable k v) #-}
{-# SPECIALIZE INLINE fromListWithSizeHint :: (Eq k, Hashable k) =>
Int -> [(k,v)] -> IO (CuckooHashTable k v) #-}
toList :: (C.HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> IO [(k,v)]
toList = stToIO . C.toList
{-# INLINE toList #-}
{-# SPECIALIZE INLINE toList :: (Eq k, Hashable k) =>
BasicHashTable k v -> IO [(k,v)] #-}
{-# SPECIALIZE INLINE toList :: (Eq k, Hashable k) =>
LinearHashTable k v -> IO [(k,v)] #-}
{-# SPECIALIZE INLINE toList :: (Eq k, Hashable k) =>
CuckooHashTable k v -> IO [(k,v)] #-}
foldM :: (C.HashTable h) =>
(a -> (k,v) -> IO a)
-> a
-> IOHashTable h k v -> IO a
foldM f seed ht = stToIO $ C.foldM f' seed ht
where
f' !i !t = unsafeIOToST $ f i t
{-# INLINE foldM #-}
{-# SPECIALIZE INLINE foldM :: (a -> (k,v) -> IO a) -> a
-> BasicHashTable k v -> IO a #-}
{-# SPECIALIZE INLINE foldM :: (a -> (k,v) -> IO a) -> a
-> LinearHashTable k v -> IO a #-}
{-# SPECIALIZE INLINE foldM :: (a -> (k,v) -> IO a) -> a
-> CuckooHashTable k v -> IO a #-}
mapM_ :: (C.HashTable h) => ((k,v) -> IO a) -> IOHashTable h k v -> IO ()
mapM_ f ht = stToIO $ C.mapM_ f' ht
where
f' = unsafeIOToST . f
{-# INLINE mapM_ #-}
{-# SPECIALIZE INLINE mapM_ :: ((k,v) -> IO a) -> BasicHashTable k v
-> IO () #-}
{-# SPECIALIZE INLINE mapM_ :: ((k,v) -> IO a) -> LinearHashTable k v
-> IO () #-}
{-# SPECIALIZE INLINE mapM_ :: ((k,v) -> IO a) -> CuckooHashTable k v
-> IO () #-}
computeOverhead :: (C.HashTable h) => IOHashTable h k v -> IO Double
computeOverhead = stToIO . C.computeOverhead
{-# INLINE computeOverhead #-}