mqtt-0.1.0.0: test/TrieSizeTest.hs
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad ( foldM, when )
import Data.IntSet as IS
import qualified Data.List.NonEmpty as NL
import qualified Data.Map as M
import System.Random ( randomIO )
import Network.MQTT.Message
import Network.MQTT.Trie as R
-- | This test shall assure that the memory consumption of the subscription
-- tree stays within certain limits.
-- This test suite runs with restricted maximum heap size.
-- The routing tree with 1 million nodes and around 3 subscriptions per node
-- took 83MB when measured.
-- We allow for some deviation, but it should not exceed 100MB heap space.
main :: IO ()
main = do
r <- randomTree 6 10 :: IO (Trie IS.IntSet)
-- We need to to something with `r` or it won't be evaluated.
when (R.size r == 0) (error "should not be 0")
randomTree :: Int -> Int -> IO (Trie IS.IntSet)
randomTree 0 _ = Trie <$> pure mempty
randomTree depth branching = Trie <$> foldM (\m e->
flip (M.insert e) m <$> (R.node
<$> randomTree (depth - 1) branching
<*> randomSet :: IO (TrieNode IS.IntSet))) M.empty
(take branching randomTreeElements)
where
randomSet :: IO (Maybe IS.IntSet)
randomSet = Just <$> f 0 IS.empty
where
f :: Int -> IS.IntSet -> IO IS.IntSet
f i accum = do
p <- randomIO :: IO Double
if p < 0.25
then pure accum
else f (succ i) $! IS.insert i accum
randomTreeElements :: [Level]
randomTreeElements =
fmap (NL.head . topicLevels) ["a","b","c","d","e","f","g","h","i","j","k","l","m" :: Topic]