{-# LANGUAGE StrictData #-}
module Network.Tox.DHT.Stamped where
import qualified Data.Foldable as F
import Data.List ((\\))
import Data.Map (Map)
import qualified Data.Map as Map
import Network.Tox.Time (Timestamp)
type Stamped a = Map Timestamp [a]
empty :: Stamped a
empty :: Stamped a
empty = Stamped a
forall k a. Map k a
Map.empty
add :: Timestamp -> a -> Stamped a -> Stamped a
add :: Timestamp -> a -> Stamped a -> Stamped a
add Timestamp
time a
x = ([a] -> [a] -> [a]) -> Timestamp -> [a] -> Stamped a -> Stamped a
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) Timestamp
time [a
x]
delete :: Eq a => Timestamp -> a -> Stamped a -> Stamped a
delete :: Timestamp -> a -> Stamped a -> Stamped a
delete Timestamp
time a
x = ([a] -> [a]) -> Timestamp -> Stamped a -> Stamped a
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust ([a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
\\ [a
x]) Timestamp
time
findStamps :: (a -> Bool) -> Stamped a -> [Timestamp]
findStamps :: (a -> Bool) -> Stamped a -> [Timestamp]
findStamps a -> Bool
p = Stamped a -> [Timestamp]
forall k a. Map k a -> [k]
Map.keys (Stamped a -> [Timestamp])
-> (Stamped a -> Stamped a) -> Stamped a -> [Timestamp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> Bool) -> Stamped a -> Stamped a
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter ((a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any a -> Bool
p)
dropOlder :: Timestamp -> Stamped a -> Stamped a
dropOlder :: Timestamp -> Stamped a -> Stamped a
dropOlder Timestamp
time = (Timestamp -> [a] -> Maybe [a]) -> Stamped a -> Stamped a
forall k a b. (k -> a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybeWithKey ((Timestamp -> [a] -> Maybe [a]) -> Stamped a -> Stamped a)
-> (Timestamp -> [a] -> Maybe [a]) -> Stamped a -> Stamped a
forall a b. (a -> b) -> a -> b
$
\Timestamp
t [a]
x -> if Timestamp
t Timestamp -> Timestamp -> Bool
forall a. Ord a => a -> a -> Bool
< Timestamp
time then Maybe [a]
forall a. Maybe a
Nothing else [a] -> Maybe [a]
forall a. a -> Maybe a
Just [a]
x
getList :: Stamped a -> [a]
getList :: Stamped a -> [a]
getList = Stamped a -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
F.concat
popFirst :: Stamped a -> (Maybe (Timestamp, a), Stamped a)
popFirst :: Stamped a -> (Maybe (Timestamp, a), Stamped a)
popFirst Stamped a
stamped =
case Stamped a -> [(Timestamp, [a])]
forall k a. Map k a -> [(k, a)]
Map.toAscList Stamped a
stamped of
[] -> (Maybe (Timestamp, a)
forall a. Maybe a
Nothing, Stamped a
stamped)
(Timestamp, [a])
assoc:[(Timestamp, [a])]
assocs -> case (Timestamp, [a])
assoc of
(Timestamp
_, []) -> Stamped a -> (Maybe (Timestamp, a), Stamped a)
forall a. Stamped a -> (Maybe (Timestamp, a), Stamped a)
popFirst (Stamped a -> (Maybe (Timestamp, a), Stamped a))
-> Stamped a -> (Maybe (Timestamp, a), Stamped a)
forall a b. (a -> b) -> a -> b
$ [(Timestamp, [a])] -> Stamped a
forall k a. Eq k => [(k, a)] -> Map k a
Map.fromAscList [(Timestamp, [a])]
assocs
(Timestamp
stamp, [a
a]) -> ((Timestamp, a) -> Maybe (Timestamp, a)
forall a. a -> Maybe a
Just (Timestamp
stamp, a
a), [(Timestamp, [a])] -> Stamped a
forall k a. Eq k => [(k, a)] -> Map k a
Map.fromAscList [(Timestamp, [a])]
assocs)
(Timestamp
stamp, a
a:[a]
as) -> ((Timestamp, a) -> Maybe (Timestamp, a)
forall a. a -> Maybe a
Just (Timestamp
stamp, a
a), [(Timestamp, [a])] -> Stamped a
forall k a. Eq k => [(k, a)] -> Map k a
Map.fromAscList ([(Timestamp, [a])] -> Stamped a)
-> [(Timestamp, [a])] -> Stamped a
forall a b. (a -> b) -> a -> b
$ (Timestamp
stamp, [a]
as)(Timestamp, [a]) -> [(Timestamp, [a])] -> [(Timestamp, [a])]
forall a. a -> [a] -> [a]
:[(Timestamp, [a])]
assocs)