-
--- Balancing functions
-
--- Loading functions
-
-{- | Convert newline and delimiter-separated text.
-
-This function converts a text in tabular format as generated by
-@gnt-instance list@ and @gnt-node list@ to a list of objects using a
-supplied conversion function.
-
--}
-loadTabular :: String -> ([String] -> (String, a))
- -> (a -> Int -> a) -> ([(String, Int)], [(Int, a)])
-loadTabular text_data convert_fn set_fn =
- let lines_data = lines text_data
- rows = map (sepSplit '|') lines_data
- kerows = (map convert_fn rows)
- idxrows = map (\ (idx, (k, v)) -> ((k, idx), (idx, set_fn v idx)))
- (zip [0..] kerows)
- in unzip idxrows
-
--- | For each instance, add its index to its primary and secondary nodes
-fixNodes :: [(Int, Node.Node)]
- -> [(Int, Instance.Instance)]
- -> [(Int, Node.Node)]
-fixNodes nl il =
- foldl' (\accu (idx, inst) ->
- let
- assocEqual = (\ (i, _) (j, _) -> i == j)
- pdx = Instance.pnode inst
- sdx = Instance.snode inst
- pold = fromJust $ lookup pdx accu
- sold = fromJust $ lookup sdx accu
- pnew = Node.setPri pold idx
- snew = Node.setSec sold idx
- ac1 = deleteBy assocEqual (pdx, pold) accu
- ac2 = deleteBy assocEqual (sdx, sold) ac1
- ac3 = (pdx, pnew):(sdx, snew):ac2
- in ac3) nl il
-
--- | Compute the longest common suffix of a [(Int, String)] list that
--- | starts with a dot
-longestDomain :: [(Int, String)] -> String
-longestDomain [] = ""
-longestDomain ((_,x):xs) =
- let
- onlyStrings = snd $ unzip xs
- in
- foldr (\ suffix accu -> if all (isSuffixOf suffix) onlyStrings
- then suffix
- else accu)
- "" $ filter (isPrefixOf ".") (tails x)
-
--- | Remove tails from the (Int, String) lists
-stripSuffix :: String -> [(Int, String)] -> [(Int, String)]
-stripSuffix suffix lst =
- let sflen = length suffix in
- map (\ (key, name) -> (key, take ((length name) - sflen) name)) lst
-
-{-| Initializer function that loads the data from a node and list file
- and massages it into the correct format. -}
-loadData :: String -- ^ Node data in text format
- -> String -- ^ Instance data in text format
- -> (Container.Container Node.Node,
- Container.Container Instance.Instance,
- String, [(Int, String)], [(Int, String)])
-loadData ndata idata =
- let
- {- node file: name mem disk -}
- (ktn, nl) = loadTabular ndata
- (\ (i:jt:jf:kt:kf:[]) -> (i, Node.create jt jf kt kf))
- Node.setIdx
- {- instance file: name mem disk -}
- (kti, il) = loadTabular idata
- (\ (i:j:k:l:m:[]) -> (i,
- Instance.create j k
- (fromJust $ lookup l ktn)
- (fromJust $ lookup m ktn)))
- Instance.setIdx
- nl2 = fixNodes nl il
- il3 = Container.fromAssocList il
- nl3 = Container.fromAssocList
- (map (\ (k, v) -> (k, Node.buildPeers v il3 (length nl2))) nl2)
- xtn = swapPairs ktn
- xti = swapPairs kti
- common_suffix = longestDomain (xti ++ xtn)
- stn = stripSuffix common_suffix xtn
- sti = stripSuffix common_suffix xti
- in
- (nl3, il3, common_suffix, stn, sti)