{-# LANGUAGE BangPatterns #-}

module Network.Wai.Middleware.Push.Referer.LimitMultiMap where

import Data.Map (Map)
import qualified Data.Map.Strict as M
import Data.Set (Set)
import qualified Data.Set as S

data LimitMultiMap k v = LimitMultiMap {
      LimitMultiMap k v -> Int
limitKey :: !Int
    , LimitMultiMap k v -> Int
limitVal :: !Int
    , LimitMultiMap k v -> Map k (Set v)
multiMap :: !(Map k (Set v))
    } deriving (LimitMultiMap k v -> LimitMultiMap k v -> Bool
(LimitMultiMap k v -> LimitMultiMap k v -> Bool)
-> (LimitMultiMap k v -> LimitMultiMap k v -> Bool)
-> Eq (LimitMultiMap k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v.
(Eq k, Eq v) =>
LimitMultiMap k v -> LimitMultiMap k v -> Bool
/= :: LimitMultiMap k v -> LimitMultiMap k v -> Bool
$c/= :: forall k v.
(Eq k, Eq v) =>
LimitMultiMap k v -> LimitMultiMap k v -> Bool
== :: LimitMultiMap k v -> LimitMultiMap k v -> Bool
$c== :: forall k v.
(Eq k, Eq v) =>
LimitMultiMap k v -> LimitMultiMap k v -> Bool
Eq, Int -> LimitMultiMap k v -> ShowS
[LimitMultiMap k v] -> ShowS
LimitMultiMap k v -> String
(Int -> LimitMultiMap k v -> ShowS)
-> (LimitMultiMap k v -> String)
-> ([LimitMultiMap k v] -> ShowS)
-> Show (LimitMultiMap k v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k v. (Show k, Show v) => Int -> LimitMultiMap k v -> ShowS
forall k v. (Show k, Show v) => [LimitMultiMap k v] -> ShowS
forall k v. (Show k, Show v) => LimitMultiMap k v -> String
showList :: [LimitMultiMap k v] -> ShowS
$cshowList :: forall k v. (Show k, Show v) => [LimitMultiMap k v] -> ShowS
show :: LimitMultiMap k v -> String
$cshow :: forall k v. (Show k, Show v) => LimitMultiMap k v -> String
showsPrec :: Int -> LimitMultiMap k v -> ShowS
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> LimitMultiMap k v -> ShowS
Show)

isEmpty :: LimitMultiMap k t -> Bool
isEmpty :: LimitMultiMap k t -> Bool
isEmpty (LimitMultiMap _ _ m :: Map k (Set t)
m) = Map k (Set t) -> Bool
forall k a. Map k a -> Bool
M.null Map k (Set t)
m

empty :: Int -> Int -> LimitMultiMap k v
empty :: Int -> Int -> LimitMultiMap k v
empty lk :: Int
lk lv :: Int
lv = Int -> Int -> Map k (Set v) -> LimitMultiMap k v
forall k v. Int -> Int -> Map k (Set v) -> LimitMultiMap k v
LimitMultiMap Int
lk Int
lv Map k (Set v)
forall k a. Map k a
M.empty

insert :: (Ord k, Ord v) => (k,v) -> LimitMultiMap k v -> LimitMultiMap k v
insert :: (k, v) -> LimitMultiMap k v -> LimitMultiMap k v
insert (k :: k
k,v :: v
v) (LimitMultiMap lk :: Int
lk lv :: Int
lv m :: Map k (Set v)
m)
  | Int
siz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<  Int
lk = let !m' :: Map k (Set v)
m' = (Maybe (Set v) -> Maybe (Set v))
-> k -> Map k (Set v) -> Map k (Set v)
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
M.alter  Maybe (Set v) -> Maybe (Set v)
alt k
k Map k (Set v)
m in Int -> Int -> Map k (Set v) -> LimitMultiMap k v
forall k v. Int -> Int -> Map k (Set v) -> LimitMultiMap k v
LimitMultiMap Int
lk Int
lv Map k (Set v)
m'
  | Int
siz Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lk = let !m' :: Map k (Set v)
m' = (Set v -> Set v) -> k -> Map k (Set v) -> Map k (Set v)
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
M.adjust Set v -> Set v
adj k
k Map k (Set v)
m in Int -> Int -> Map k (Set v) -> LimitMultiMap k v
forall k v. Int -> Int -> Map k (Set v) -> LimitMultiMap k v
LimitMultiMap Int
lk Int
lv Map k (Set v)
m'
  | Bool
otherwise = String -> LimitMultiMap k v
forall a. HasCallStack => String -> a
error "insert"
  where
    siz :: Int
siz = Map k (Set v) -> Int
forall k a. Map k a -> Int
M.size Map k (Set v)
m
    alt :: Maybe (Set v) -> Maybe (Set v)
alt Nothing          = Set v -> Maybe (Set v)
forall a. a -> Maybe a
Just (Set v -> Maybe (Set v)) -> Set v -> Maybe (Set v)
forall a b. (a -> b) -> a -> b
$ v -> Set v
forall a. a -> Set a
S.singleton v
v
    alt s :: Maybe (Set v)
s@(Just set :: Set v
set)
      | Set v -> Int
forall a. Set a -> Int
S.size Set v
set Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lv = Maybe (Set v)
s
      | Bool
otherwise        = Set v -> Maybe (Set v)
forall a. a -> Maybe a
Just (Set v -> Maybe (Set v)) -> Set v -> Maybe (Set v)
forall a b. (a -> b) -> a -> b
$ v -> Set v -> Set v
forall a. Ord a => a -> Set a -> Set a
S.insert v
v Set v
set
    adj :: Set v -> Set v
adj set :: Set v
set
      | Set v -> Int
forall a. Set a -> Int
S.size Set v
set Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lv = Set v
set
      | Bool
otherwise        = v -> Set v -> Set v
forall a. Ord a => a -> Set a -> Set a
S.insert v
v Set v
set

lookup :: Ord k => k -> LimitMultiMap k v -> [v]
lookup :: k -> LimitMultiMap k v -> [v]
lookup k :: k
k (LimitMultiMap _ _ m :: Map k (Set v)
m) = case k -> Map k (Set v) -> Maybe (Set v)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
k Map k (Set v)
m of
  Nothing  -> []
  Just set :: Set v
set -> Set v -> [v]
forall a. Set a -> [a]
S.toList Set v
set