module BTree.Merge ( mergeTrees
, mergeLeaves
, sizedProducerForTree
) where
import Control.Applicative
import Data.Foldable
import Control.Monad.State hiding (forM_)
import Control.Monad.Catch
import Data.Binary
import Control.Lens
import Pipes
import Pipes.Interleave
import Prelude hiding (sum)
import BTree.Types
import BTree.Builder
import BTree.Walk
mergeLeaves :: (MonadMask m, MonadIO m, Functor m, Binary k, Binary e, Ord k)
=> (e -> e -> m e)
-> Order
-> FilePath
-> [(Size, Producer (BLeaf k e) m ())]
-> m ()
mergeLeaves append destOrder destFile producers = do
let size = sum $ map fst producers
fromOrderedToFile destOrder size destFile $
mergeM doAppend (map snd producers)
where
doAppend (BLeaf k e) (BLeaf _ e') = BLeaf k <$> append e e'
{-# INLINE mergeLeaves #-}
mergeTrees :: (MonadMask m, MonadIO m, Functor m, Binary k, Binary e, Ord k)
=> (e -> e -> m e)
-> Order
-> FilePath
-> [LookupTree k e]
-> m ()
mergeTrees append destOrder destFile trees = do
mergeLeaves append destOrder destFile
$ map sizedProducerForTree trees
{-# INLINE mergeTrees #-}
sizedProducerForTree :: (Monad m, Binary k, Binary e)
=> LookupTree k e
-> (Size, Producer (BLeaf k e) m ())
sizedProducerForTree lt = (lt ^. ltHeader . btSize, void $ walkLeaves lt)