From 0f9f0fc472de3ae8b4a2ae3ed503a0872fc94b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 26 Aug 2020 21:30:42 +0200 Subject: wip: RefMap --- src/RefMap.hs | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/RefMap.hs diff --git a/src/RefMap.hs b/src/RefMap.hs new file mode 100644 index 0000000..500ea4b --- /dev/null +++ b/src/RefMap.hs @@ -0,0 +1,85 @@ +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 -- cgit v1.2.3