on c2b8ccd help sign in
patch/src/Data/FastMutableIntMap.hs
80 lines 2.4 kB history raw
1{-# LANGUAGE DeriveFunctor #-}
2{-# LANGUAGE DeriveFoldable #-}
3{-# LANGUAGE DeriveTraversable #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE TypeFamilies #-}
6module Data.FastMutableIntMap
7 ( FastMutableIntMap
8 , new
9 , newEmpty
10 , insert
11 , isEmpty
12 , getFrozenAndClear
13 , size
14 , applyPatch
15 , PatchIntMap (..)
16 , traverseIntMapPatchWithKey
17 , lookup
18 , forIntersectionWithImmutable_
19 , for_
20 , patchIntMapNewElements
21 , patchIntMapNewElementsMap
22 , getDeletions
23 ) where
25--TODO: Pure JS version
26--TODO: Fast copy to FastIntMap
27--TODO: Fast patch type
29import Control.Monad.IO.Class
30import Data.Foldable (traverse_)
31import Data.IORef
32import Data.IntMap.Strict (IntMap)
33import qualified Data.IntMap.Strict as IntMap
34import Data.Maybe
35import Prelude hiding (lookup)
36import Reflex.Patch.Class
37import Reflex.Patch.IntMap
39newtype FastMutableIntMap a = FastMutableIntMap (IORef (IntMap a))
41new :: IntMap a -> IO (FastMutableIntMap a)
42new m = FastMutableIntMap <$> newIORef m
44newEmpty :: IO (FastMutableIntMap a)
45newEmpty = FastMutableIntMap <$> newIORef IntMap.empty
47insert :: FastMutableIntMap a -> Int -> a -> IO ()
48insert (FastMutableIntMap r) k v = modifyIORef' r $ IntMap.insert k v
50lookup :: FastMutableIntMap a -> Int -> IO (Maybe a)
51lookup (FastMutableIntMap r) k = IntMap.lookup k <$> readIORef r
53forIntersectionWithImmutable_ :: MonadIO m => FastMutableIntMap a -> IntMap b -> (a -> b -> m ()) -> m ()
54forIntersectionWithImmutable_ (FastMutableIntMap r) b f = do
55 a <- liftIO $ readIORef r
56 traverse_ (uncurry f) $ IntMap.intersectionWith (,) a b
58for_ :: MonadIO m => FastMutableIntMap a -> (a -> m ()) -> m ()
59for_ (FastMutableIntMap r) f = do
60 a <- liftIO $ readIORef r
61 traverse_ f a
63isEmpty :: FastMutableIntMap a -> IO Bool
64isEmpty (FastMutableIntMap r) = IntMap.null <$> readIORef r
66size :: FastMutableIntMap a -> IO Int
67size (FastMutableIntMap r) = IntMap.size <$> readIORef r
69-- | Make an immutable snapshot of the datastructure and clear it
70getFrozenAndClear :: FastMutableIntMap a -> IO (IntMap a)
71getFrozenAndClear (FastMutableIntMap r) = do
72 result <- readIORef r
73 writeIORef r IntMap.empty
74 return result
76applyPatch :: FastMutableIntMap a -> PatchIntMap a -> IO (IntMap a)
77applyPatch (FastMutableIntMap r) p@(PatchIntMap m) = do
78 v <- readIORef r
79 writeIORef r $! applyAlways p v
80 return $ IntMap.intersection v m