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.Internal (Fingerprint, TypeRep (TypeRep))
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 :: !(HashTable s HKey' Dynamic)
, hSetCount :: !(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 (TypeRep f _ _ _) = 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