{-# LANGUAGE TypeFamilies #-}
module Data.FastMutableIntMap
( FastMutableIntMap
, new
, newEmpty
, insert
, isEmpty
, getFrozenAndClear
, size
, applyPatch
, PatchIntMap (..)
, traverseIntMapPatchWithKey
, lookup
, forIntersectionWithImmutable_
, for_
, patchIntMapNewElements
, patchIntMapNewElementsMap
, getDeletions
, toList
) where
import Prelude hiding (lookup)
import Control.Monad.IO.Class
import Data.Foldable (traverse_)
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IntMap
import Data.IORef
import Data.Patch.Class
import Data.Patch.IntMap
newtype FastMutableIntMap a = FastMutableIntMap (IORef (IntMap a))
new :: IntMap a -> IO (FastMutableIntMap a)
new :: forall a. IntMap a -> IO (FastMutableIntMap a)
new IntMap a
m = IORef (IntMap a) -> FastMutableIntMap a
forall a. IORef (IntMap a) -> FastMutableIntMap a
FastMutableIntMap (IORef (IntMap a) -> FastMutableIntMap a)
-> IO (IORef (IntMap a)) -> IO (FastMutableIntMap a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntMap a -> IO (IORef (IntMap a))
forall a. a -> IO (IORef a)
newIORef IntMap a
m
newEmpty :: IO (FastMutableIntMap a)
newEmpty :: forall a. IO (FastMutableIntMap a)
newEmpty = IORef (IntMap a) -> FastMutableIntMap a
forall a. IORef (IntMap a) -> FastMutableIntMap a
FastMutableIntMap (IORef (IntMap a) -> FastMutableIntMap a)
-> IO (IORef (IntMap a)) -> IO (FastMutableIntMap a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntMap a -> IO (IORef (IntMap a))
forall a. a -> IO (IORef a)
newIORef IntMap a
forall a. IntMap a
IntMap.empty
insert :: FastMutableIntMap a -> Int -> a -> IO ()
insert :: forall a. FastMutableIntMap a -> Int -> a -> IO ()
insert (FastMutableIntMap IORef (IntMap a)
r) Int
k a
v = IORef (IntMap a) -> (IntMap a -> IntMap a) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (IntMap a)
r ((IntMap a -> IntMap a) -> IO ())
-> (IntMap a -> IntMap a) -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert Int
k a
v
lookup :: FastMutableIntMap a -> Int -> IO (Maybe a)
lookup :: forall a. FastMutableIntMap a -> Int -> IO (Maybe a)
lookup (FastMutableIntMap IORef (IntMap a)
r) Int
k = Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
k (IntMap a -> Maybe a) -> IO (IntMap a) -> IO (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
forIntersectionWithImmutable_ :: MonadIO m => FastMutableIntMap a -> IntMap b -> (a -> b -> m ()) -> m ()
forIntersectionWithImmutable_ :: forall (m :: * -> *) a b.
MonadIO m =>
FastMutableIntMap a -> IntMap b -> (a -> b -> m ()) -> m ()
forIntersectionWithImmutable_ (FastMutableIntMap IORef (IntMap a)
r) IntMap b
b a -> b -> m ()
f = do
a <- IO (IntMap a) -> m (IntMap a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IntMap a) -> m (IntMap a)) -> IO (IntMap a) -> m (IntMap a)
forall a b. (a -> b) -> a -> b
$ IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
traverse_ (uncurry f) $ IntMap.intersectionWith (,) a b
for_ :: MonadIO m => FastMutableIntMap a -> (a -> m ()) -> m ()
for_ :: forall (m :: * -> *) a.
MonadIO m =>
FastMutableIntMap a -> (a -> m ()) -> m ()
for_ (FastMutableIntMap IORef (IntMap a)
r) a -> m ()
f = do
a <- IO (IntMap a) -> m (IntMap a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IntMap a) -> m (IntMap a)) -> IO (IntMap a) -> m (IntMap a)
forall a b. (a -> b) -> a -> b
$ IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
traverse_ f a
isEmpty :: FastMutableIntMap a -> IO Bool
isEmpty :: forall a. FastMutableIntMap a -> IO Bool
isEmpty (FastMutableIntMap IORef (IntMap a)
r) = IntMap a -> Bool
forall a. IntMap a -> Bool
IntMap.null (IntMap a -> Bool) -> IO (IntMap a) -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
size :: FastMutableIntMap a -> IO Int
size :: forall a. FastMutableIntMap a -> IO Int
size (FastMutableIntMap IORef (IntMap a)
r) = IntMap a -> Int
forall a. IntMap a -> Int
IntMap.size (IntMap a -> Int) -> IO (IntMap a) -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
getFrozenAndClear :: FastMutableIntMap a -> IO (IntMap a)
getFrozenAndClear :: forall a. FastMutableIntMap a -> IO (IntMap a)
getFrozenAndClear (FastMutableIntMap IORef (IntMap a)
r) = do
result <- IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
writeIORef r IntMap.empty
return result
applyPatch :: FastMutableIntMap a -> PatchIntMap a -> IO (IntMap a)
applyPatch :: forall a. FastMutableIntMap a -> PatchIntMap a -> IO (IntMap a)
applyPatch (FastMutableIntMap IORef (IntMap a)
r) p :: PatchIntMap a
p@(PatchIntMap IntMap (Maybe a)
m) = do
v <- IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
writeIORef r $! applyAlways p v
return $ IntMap.intersection v m
toList :: FastMutableIntMap a -> IO [(Int, a)]
toList :: forall a. FastMutableIntMap a -> IO [(Int, a)]
toList (FastMutableIntMap IORef (IntMap a)
r) = IntMap a -> [(Int, a)]
forall a. IntMap a -> [(Int, a)]
IntMap.toList (IntMap a -> [(Int, a)]) -> IO (IntMap a) -> IO [(Int, a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r