1 module Network.DNS.DomainMap
21 import qualified Data.List as L hiding (null)
23 import qualified Data.Trie as T
24 import Data.Trie (Trie)
25 import Network.DNS.Message
26 import Prelude hiding (null, lookup)
29 newtype DomainMap a = DM (Node a)
31 data Node a = Node (Maybe a) (Trie (Node a))
39 emptyNode = Node Nothing T.empty
42 null :: DomainMap a -> Bool
43 null (DM n) = nodeNull n
46 nodeNull :: Node a -> Bool
47 nodeNull (Node (Just _) _) = False
48 nodeNull (Node Nothing t) = all nodeNull $ T.toListBy (\ _ a -> a) t
51 singleton :: DomainName -> a -> DomainMap a
53 = insert key value empty
56 size :: forall a. DomainMap a -> Int
57 size (DM n) = nodeSize n
60 nodeSize :: Node a -> Int
62 = let x = if isJust m then
66 xs = map nodeSize $ T.toListBy (\ _ a -> a) t
71 fromList :: forall a. [(DomainName, a)] -> DomainMap a
73 fromList ((k, v) : xs) = insert k v $ fromList xs
76 toList :: forall a. DomainMap a -> [(DomainName, a)]
77 toList (DM root) = toList' rootName root
79 toList' :: DomainName -> Node a -> [(DomainName, a)]
80 toList' soFar (Node m t)
82 Just v -> [(soFar, v)]
84 xs = concat $ map toList'' $ T.toList t
88 toList'' :: (DomainLabel, Node a) -> [(DomainName, a)]
89 toList'' (l, n) = toList' (consLabel l soFar) n
92 toListBy :: forall a b. DomainMap a -> (DomainName -> a -> b) -> [b]
93 toListBy dm f = map (uncurry f) $ toList dm
96 nearest :: forall a. DomainName -> DomainMap a -> Maybe a
97 nearest key (DM root) = nearest' key' root
100 key' = reverse $ nameToLabels key
102 nearest' :: [DomainLabel] -> Node a -> Maybe a
103 nearest' [] _ = error ("Illegal key: " ++ show key)
104 nearest' (_:[]) (Node m _) = m
105 nearest' (x:xs) (Node m t) = let nearer = do subNode' <- T.lookup x t
108 if isJust nearer then
114 lookup :: forall a. DomainName -> DomainMap a -> Maybe a
115 lookup key (DM root) = lookup' key' root
117 key' :: [DomainLabel]
118 key' = reverse $ nameToLabels key
120 lookup' :: [DomainLabel] -> Node a -> Maybe a
121 lookup' [] _ = error ("Illegal key: " ++ show key)
122 lookup' (_:[]) (Node m _) = m
123 lookup' (x:xs) (Node _ t) = do subNode' <- T.lookup x t
127 insert :: forall a. DomainName -> a -> DomainMap a -> DomainMap a
128 insert key value (DM root) = DM $ insert' key' root
130 key' :: [DomainLabel]
131 key' = reverse $ nameToLabels key
133 insert' :: [DomainLabel] -> Node a -> Node a
134 insert' [] _ = error ("Illegal key: " ++ show key)
135 insert' (_:[]) (Node _ t) = Node (Just value) t
136 insert' (x:xs) (Node m t) = let subNode' = case T.lookup x t of
137 Just subNode -> insert' xs subNode
138 Nothing -> insert' xs emptyNode
139 trie' = T.insert x subNode' t
143 delete :: forall a. DomainName -> DomainMap a -> DomainMap a
144 delete key (DM root) = DM $ delete' key' root
146 key' :: [DomainLabel]
147 key' = reverse $ nameToLabels key
149 delete' :: [DomainLabel] -> Node a -> Node a
150 delete' [] _ = error ("Illegal key: " ++ show key)
151 delete' (_:[]) (Node _ t) = Node Nothing t
152 delete' (x:xs) (Node m t) = let subNode' = case T.lookup x t of
153 Just subNode -> delete' xs subNode
155 trie' = if nodeNull subNode' then
158 T.insert x subNode' t