{-# LANGUAGE GADTs#-}
module Data.HMemDb.References
    (CRef(CRef), Ref(Ref, refContent, refIndex), deCRef, deRef) where
import Control.Concurrent.STM (TVar, readTVar)
import Control.Monad.Trans.Class (lift)
import Data.Function (on)
import Data.HMemDb.Binary (MS)
import Data.HMemDb.Utils (liftMaybe)
data Ref r = Ref {refContent :: TVar (Maybe r), refIndex :: Integer}
instance Eq (Ref r) where (==) = (==) `on` refIndex
instance Ord (Ref r) where compare = compare `on` refIndex
deRef :: Ref r -> MS r
deRef ref = lift (readTVar $ refContent ref) >>= liftMaybe
data CRef a where CRef :: Ref r -> (r -> MS a) -> CRef a
cRefIndex :: CRef a -> Integer
cRefIndex (CRef ref _) = refIndex ref
instance Eq (CRef a) where (==) = (==) `on` cRefIndex
instance Ord (CRef a) where compare = compare `on` cRefIndex
deCRef :: CRef a -> MS a
deCRef (CRef ref to) = deRef ref >>= to