@@ -1,18 +1,15 @@
1−{-# LANGUAGE CPP #-}
1+{-# LANGUAGE CPP, BangPatterns #-}
3module Network.Wai.Handler.Warp.MultiMap (
3module Network.Wai.Handler.Warp.MultiMap (
5− , Some(..)
5+ , isEmpty
7 , singleton
7 , singleton
10 , searchWith
10 , searchWith
12 , pruneWith
11 , pruneWith
@@ -21,30 +18,27 @@ import Control.Applicative ((<$>))
22import Data.IntMap (IntMap)
19import Data.IntMap (IntMap)
23import qualified Data.IntMap as I
20import qualified Data.IntMap as I
21+import qualified Network.Wai.Handler.Warp.Some as S
25----------------------------------------------------------------
23----------------------------------------------------------------
27−-- | One ore more list to implement multimap.
25+type MMap v = IntMap (S.Some v)
29− | Tom !a !(Some a) -- Two or more
32−{-
27+----------------------------------------------------------------
33−cons :: Some a -> a -> Some a
37−top :: Some a -> a
29+-- | O(1)
38−top (One x) = x
30+isEmpty :: MMap v -> Bool
39−top (Tom x _) = x
31+isEmpty = I.null
41−union :: Some a -> Some a -> Some a
33+-- | O(1)
42−union (One x) s = Tom x s
34+empty :: MMap v
43−union (Tom x xs) s = union xs (Tom x s)
35+empty = I.empty
45----------------------------------------------------------------
37----------------------------------------------------------------
47−type MMap v = IntMap (Some v)
39+-- | O(1)
40+singleton :: Int -> v -> MMap v
41+singleton k v = I.singleton k (S.singleton v)
49----------------------------------------------------------------
43----------------------------------------------------------------
@@ -52,35 +46,19 @@ type MMap v = IntMap (Some v)
52search :: Int -> MMap v -> Maybe v
46search :: Int -> MMap v -> Maybe v
53search k m = case I.lookup k m of
47search k m = case I.lookup k m of
54 Nothing -> Nothing
48 Nothing -> Nothing
55− Just s -> Just $! top s
49+ Just s -> Just $! S.top s
57-- | O(log n)
51-- | O(log n)
58−searchWith :: Int -> (Some v -> Maybe v) -> MMap v -> Maybe v
52+searchWith :: Int -> (v -> Bool) -> MMap v -> Maybe v
59searchWith k f m = case I.lookup k m of
53searchWith k f m = case I.lookup k m of
60 Nothing -> Nothing
54 Nothing -> Nothing
61− Just s -> f s
55+ Just s -> S.lookupWith f s
63−----------------------------------------------------------------
66−isEmpty :: MMap v -> Bool
73−----------------------------------------------------------------
76−singleton :: Int -> v -> MMap v
77−singleton k v = I.singleton k (One v)
79----------------------------------------------------------------
57----------------------------------------------------------------
81-- | O(log n)
59-- | O(log n)
82insert :: Int -> v -> MMap v -> MMap v
60insert :: Int -> v -> MMap v -> MMap v
83−insert k v m = I.insertWith union k (One v) m
61+insert k v m = I.insertWith S.union k (S.singleton v) m
85----------------------------------------------------------------
63----------------------------------------------------------------
@@ -88,33 +66,26 @@ insert k v m = I.insertWith union k (One v) m
88toList :: MMap v -> [v]
66toList :: MMap v -> [v]
89toList m = concatMap f $ I.toAscList m
67toList m = concatMap f $ I.toAscList m
91− f (_,s) = go s []
69+ f (_,s) = S.toList s
93− go (One x) acc = x : acc
94− go (Tom x xs) acc = go xs (x : acc)
96−----------------------------------------------------------------
99−fromSortedList :: [(Int,Some v)] -> MMap v
100−fromSortedList = I.fromAscList
102−----------------------------------------------------------------
105−toSortedList :: MMap v -> [(Int,Some v)]
106−toSortedList = I.toAscList
108----------------------------------------------------------------
71----------------------------------------------------------------
111pruneWith :: MMap v
74pruneWith :: MMap v
112− -> ((Int,Some v) -> IO [(Int, Some v)])
75+ -> (v -> IO Bool)
113 -> IO (MMap v)
76 -> IO (MMap v)
114−pruneWith m action = fromSortedList . concat <$> mapM action (toSortedList m)
77+pruneWith m action = I.fromAscList <$> go (I.toAscList m)
81+ mt <- S.prune action s
84+ Nothing -> return lst
85+ Just t -> return $ (k,t) : lst
116----------------------------------------------------------------
87----------------------------------------------------------------
118-- O(n + m) where N is the size of the second argument
89-- O(n + m) where N is the size of the second argument
119merge :: MMap v -> MMap v -> MMap v
90merge :: MMap v -> MMap v -> MMap v
120−merge m1 m2 = I.unionWith union m1 m2
91+merge m1 m2 = I.unionWith S.union m1 m2