module RefMap ( RefMap, null, size, member, notMember, fromList, toList, empty, lookup, insert, insertNew, elems, delete, adjust, assocs, ) where import Storage.Internal (RefDigest, Ref) import Data.IntMap (IntMap) import qualified Data.IntMap as IM data RefMap a = IntMap [(RefDigest, a)] instance Functor RefMap where fmap f (RefMap im) = RefMap (fmap f im) instance Foldable RefMap where foldMap f (RefMap im) = foldMap f im instance Traversable RefMap where traverse f (RefMap im) = RefMap <$> traverse f im splitRef :: Ref -> (Int, Digest) splitRef r = null :: RefMap a -> Bool null (RefMap im) = IM.null im size :: RefMap a -> Int size (RefMap im) = sum $ map length $ IM.elems im member :: Ref -> RefMap a -> Bool member r (RefMap im) | Just xs <- IM.lookup i im = any ((==d) . fst) xs | otherwise = False where (i, d) = splitRef r notMember :: (Integral i) => i -> RefMap a -> Bool notMember i (RefMap im) = IM.notMember (fromIntegral i) im fromList :: (Integral i) => [(i, a)] -> RefMap a fromList xs = IDMap (maximum (map fst xs) + 1) $ IM.fromList $ map (\(i,x) -> (fromIntegral i, x)) xs toList :: (Integral i) => RefMap a -> [(i, a)] toList (RefMap im) = map (\(i,x) -> (fromIntegral i, x)) $ IM.toList im empty :: (Integral i) => RefMap a empty = IDMap 1 IM.empty lookup :: (Integral i, Monad m) => i -> RefMap a -> m a lookup i (RefMap im) = maybe (fail "IDMap.lookup: item not found") return $ IM.lookup (fromIntegral i) im insert :: (Integral i) => i -> a -> RefMap a -> RefMap a insert i x (RefMap im) = IDMap (max n (i+1)) (IM.insert (fromIntegral i) x im) insertNew :: (Integral i) => a -> RefMap a -> (RefMap a, i) insertNew x (RefMap im) = (IDMap (n+1) $ IM.insert (fromIntegral n) x im, n) elems :: RefMap a -> [a] elems (RefMap im) = IM.elems im delete :: (Integral i) => i -> RefMap a -> RefMap a delete i (RefMap im) = RefMap $ IM.delete (fromIntegral i) im adjust :: (Integral i) => (a -> a) -> i -> RefMap a -> RefMap a adjust f i (RefMap im) = RefMap $ IM.adjust f (fromIntegral i) im assocs :: (Integral i) => RefMap a -> [(i,a)] assocs (RefMap im) = map (\(i,x) -> (fromIntegral i, x)) $ IM.assocs im