module Data.Homeomorphic.SimpleParallel where
import qualified Data.Map as Map
import qualified Data.IntMap as IntMap
import Data.Homeomorphic.Internal
import Data.List
import Debug.Trace
data Homeomorphic k v = Homeomorphic (IntMap.IntMap v) (H k)
data H k = H [Int] (Map.Map (Int,k) (H k))
empty :: Homeomorphic k v
empty = Homeomorphic IntMap.empty emptyH
emptyH = H [] Map.empty
insert :: Ord k => Shell k -> v -> Homeomorphic k v -> Homeomorphic k v
insert k v (Homeomorphic a b) = Homeomorphic (IntMap.insert i v a) (add (flatten k) b)
where
i = IntMap.size a
flatten (Shell a b c) = (b,a) : concatMap flatten c
add [] (H a b) = H (i:a) b
add (x:xs) (H a b) = H a b2
where
b2 = Map.insertWith comb x (add xs emptyH) b
comb new old = add xs old
find :: Ord k => Shell k -> Homeomorphic k v -> [v]
find k (Homeomorphic a b) = map (a IntMap.!) res
where res = reverse $ sort $ nub $ findIds [k] b
findOne :: Ord k => Shell k -> Homeomorphic k v -> Maybe v
findOne k (Homeomorphic a b) =
case findIds [k] b of
[] -> Nothing
i:_ -> Just $ a IntMap.! i
findIds :: Ord k => [Shell k] -> H k -> [Int]
findIds [] (H ans _ ) = ans
findIds (k:ks) (H _ mp) = concatMap f (shell k)
where
f (a,b) = maybe [] (findIds $ b++ks) $ Map.lookup a mp
shell (Shell a b c) = ((b,a), c) : concatMap shell c