Ignore-this: f58ceb5e1068be132b0a67a851b096f4 This has two advantages: 1. TemplateHaskell is painfully slow. There, I said it. 2. TemplateHaskell doesn't yet support some extensions that can be usefull for this library. Specifically the MagicHash extension. darcs-hash:20090813023321-a4fee-0da13d0da6454f6ba3bd111ed6b80268d9e1b45c
43 lines
1.8 KiB
Haskell
43 lines
1.8 KiB
Haskell
module Data.Map.Static.Builder where
|
|
|
|
import Data.Static
|
|
import Data.Array.Static.Builder
|
|
|
|
import Data.List
|
|
import Data.Ord
|
|
import Data.Bits
|
|
|
|
buildStaticMap :: (StaticElement i,StaticElement e,Ord i) => [(i,e)] -> String
|
|
buildStaticMap lst = let step :: Int -> [(i,e)] -> [(Int,(i,e))]
|
|
step n chunk = let ss = findSplitSize (length chunk)
|
|
(h,d:t) = splitAt ss chunk
|
|
in if null chunk
|
|
then []
|
|
else (n,d):((step (n*2) h)++(step (n*2+1) t))
|
|
checkHeap n [] = []
|
|
checkHeap n ((c,x):xs) = if c == n
|
|
then x:checkHeap (n+1) xs
|
|
else error $ "Heap is not consistent: Should be "++show n++" but is "++show c
|
|
uheap = sortBy (comparing fst) (step 1 slst)
|
|
slst = sortBy (comparing fst) lst
|
|
heap = checkHeap 1 $ sortBy (comparing fst) (step 1 slst)
|
|
len = length heap
|
|
in "StaticMap ("++buildStaticArray (1,len) (map fst heap)++") ("++buildStaticArray (1,len) (map snd heap)++")"
|
|
|
|
maxSize :: Int -> Int
|
|
maxSize d = (1 `shiftL` d) - 1
|
|
|
|
treeDepth :: Int -> Int
|
|
treeDepth sz = find' [0..]
|
|
where
|
|
find' (x:xs) = if 1 `shiftL` x > sz
|
|
then x
|
|
else find' xs
|
|
|
|
findSplitSize :: Int -> Int
|
|
findSplitSize len = let depth = treeDepth len
|
|
free = (maxSize depth) - len
|
|
in if free <= (1 `shiftL` (depth - 2))
|
|
then maxSize (depth - 1)
|
|
else len - (maxSize (depth - 2)) - 1
|