{-# 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 :: 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 :: 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 :: 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 :: 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_ :: FastMutableIntMap a -> IntMap b -> (a -> b -> m ()) -> m ()
forIntersectionWithImmutable_ (FastMutableIntMap IORef (IntMap a)
r) IntMap b
b a -> b -> m ()
f = do
IntMap a
a <- IO (IntMap a) -> m (IntMap 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
((a, b) -> m ()) -> IntMap (a, b) -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((a -> b -> m ()) -> (a, b) -> m ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> b -> m ()
f) (IntMap (a, b) -> m ()) -> IntMap (a, b) -> m ()
forall a b. (a -> b) -> a -> b
$ (a -> b -> (a, b)) -> IntMap a -> IntMap b -> IntMap (a, b)
forall a b c. (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
IntMap.intersectionWith (,) IntMap a
a IntMap b
b
for_ :: MonadIO m => FastMutableIntMap a -> (a -> m ()) -> m ()
for_ :: FastMutableIntMap a -> (a -> m ()) -> m ()
for_ (FastMutableIntMap IORef (IntMap a)
r) a -> m ()
f = do
IntMap a
a <- IO (IntMap a) -> m (IntMap 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
(a -> m ()) -> IntMap a -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ a -> m ()
f IntMap a
a
isEmpty :: FastMutableIntMap a -> IO Bool
isEmpty :: 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 :: 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 :: FastMutableIntMap a -> IO (IntMap a)
getFrozenAndClear (FastMutableIntMap IORef (IntMap a)
r) = do
IntMap a
result <- IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
IORef (IntMap a) -> IntMap a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (IntMap a)
r IntMap a
forall a. IntMap a
IntMap.empty
IntMap a -> IO (IntMap a)
forall (m :: * -> *) a. Monad m => a -> m a
return IntMap a
result
applyPatch :: FastMutableIntMap a -> PatchIntMap a -> IO (IntMap a)
applyPatch :: FastMutableIntMap a -> PatchIntMap a -> IO (IntMap a)
applyPatch (FastMutableIntMap IORef (IntMap a)
r) p :: PatchIntMap a
p@(PatchIntMap IntMap (Maybe a)
m) = do
IntMap a
v <- IORef (IntMap a) -> IO (IntMap a)
forall a. IORef a -> IO a
readIORef IORef (IntMap a)
r
IORef (IntMap a) -> IntMap a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (IntMap a)
r (IntMap a -> IO ()) -> IntMap a -> IO ()
forall a b. (a -> b) -> a -> b
$! PatchIntMap a
-> PatchTarget (PatchIntMap a) -> PatchTarget (PatchIntMap a)
forall p. Patch p => p -> PatchTarget p -> PatchTarget p
applyAlways PatchIntMap a
p IntMap a
PatchTarget (PatchIntMap a)
v
IntMap a -> IO (IntMap a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IntMap a -> IO (IntMap a)) -> IntMap a -> IO (IntMap a)
forall a b. (a -> b) -> a -> b
$ IntMap a -> IntMap (Maybe a) -> IntMap a
forall a b. IntMap a -> IntMap b -> IntMap a
IntMap.intersection IntMap a
v IntMap (Maybe a)
m
toList :: FastMutableIntMap a -> IO [(Int, a)]
toList :: 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