module Data.HSet.Mutable ( HKey , HSet , new , insert , lookup , delete ) where import Data.HSet.Types import Prelude hiding (lookup, length) import Data.Maybe (fromMaybe) import Data.Typeable (typeOf, typeRepFingerprint) import GHC.Fingerprint import Data.Dynamic import Data.HashTable.ST.Basic (HashTable) import qualified Data.HashTable.ST.Basic as HT import Control.Monad.ST data HSet s = HSet { hSetValues :: {-# UNPACK #-} !(HashTable s HKey' Dynamic) , hSetCount :: {-# UNPACK #-} !(HashTable s Fingerprint Int) } new :: ST s (HSet s) new = HSet <$> HT.new <*> HT.new insert :: Typeable a => a -> HSet s -> ST s (HKey a) insert x (HSet xs count) = do let f = typeRepFingerprint $ typeOf x c <- fromMaybe 0 <$> HT.lookup count f HT.insert count f (c+1) let k = HKey' f c HT.insert xs k (toDyn x) pure (HKey k) lookup :: Typeable a => HKey a -> HSet s -> ST s (Maybe a) lookup (HKey k) (HSet xs _) = (>>= fromDynamic) <$> HT.lookup xs k delete :: HKey a -> HSet s -> ST s () delete (HKey k@(HKey' f _)) (HSet xs count) = do HT.delete count f HT.delete xs k