@@ -12,11 +12,13 @@ module Database.LSMTree.Internal.MergingTree (
1212 ) where
1313
1414import Control.Concurrent.Class.MonadMVar.Strict
15- import Control.Monad (filterM )
15+ import Control.Monad ((<$!>) )
1616import Control.Monad.Class.MonadThrow (MonadMask )
1717import Control.Monad.Primitive
1818import Control.RefCount
1919import Data.Foldable (traverse_ )
20+ import Data.Vector (Vector )
21+ import qualified Data.Vector as V
2022import Database.LSMTree.Internal.MergingRun (MergingRun )
2123import qualified Database.LSMTree.Internal.MergingRun as MR
2224import Database.LSMTree.Internal.Run (Run )
@@ -88,12 +90,12 @@ data PendingMerge m h =
8890 -- i.e. its (merging) runs and finally a union merge (if that table
8991 -- already contained a union).
9092 PendingLevelMerge
91- ! [ PreExistingRun m h ]
93+ ! ( Vector ( PreExistingRun m h ))
9294 ! (Maybe (Ref (MergingTree m h )))
9395
9496 -- | Each input is the entire content of a table (as a merging tree).
9597 | PendingUnionMerge
96- ! [ Ref (MergingTree m h )]
98+ ! ( Vector ( Ref (MergingTree m h )))
9799
98100data PreExistingRun m h =
99101 PreExistingRun ! (Ref (Run m h ))
@@ -139,15 +141,15 @@ newPendingLevelMerge prs mmt = do
139141 CompletedTreeMerge <$> dupRef r
140142
141143 _ -> PendingTreeMerge <$>
142- (PendingLevelMerge <$> traverse dupPreExistingRun prs
144+ (PendingLevelMerge <$> traverse dupPreExistingRun ( V. fromList prs)
143145 <*> dupMaybeMergingTree mmt)
144146
145147 newMergeTree mergeTreeState
146148 where
147149 dupPreExistingRun (PreExistingRun r) =
148- PreExistingRun <$> dupRef r
150+ PreExistingRun <$! > dupRef r
149151 dupPreExistingRun (PreExistingMergingRun mr) =
150- PreExistingMergingRun <$> dupRef mr
152+ PreExistingMergingRun <$! > dupRef mr
151153
152154 dupMaybeMergingTree :: Maybe (Ref (MergingTree m h ))
153155 -> m (Maybe (Ref (MergingTree m h )))
@@ -156,7 +158,7 @@ newPendingLevelMerge prs mmt = do
156158 isempty <- isStructurallyEmpty mt
157159 if isempty
158160 then return Nothing
159- else Just <$> dupRef mt
161+ else Just <$! > dupRef mt
160162
161163-- | Create a new 'MergingTree' representing the union of one or more merging
162164-- trees. This is for unioning the content of multiple tables (represented
@@ -178,10 +180,12 @@ newPendingUnionMerge ::
178180 => [Ref (MergingTree m h )]
179181 -> m (Ref (MergingTree m h ))
180182newPendingUnionMerge mts = do
181- mts' <- mapM dupRef =<< filterM (fmap not . isStructurallyEmpty) mts
182- case mts' of
183- [mt] -> return mt
184- _ -> newMergeTree (PendingTreeMerge (PendingUnionMerge mts'))
183+ mts' <- V. mapM dupRef
184+ =<< V. filterM (fmap not . isStructurallyEmpty) (V. fromList mts)
185+ case V. uncons mts' of
186+ Just (mt, mts'') | V. null mts''
187+ -> return mt
188+ _ -> newMergeTree (PendingTreeMerge (PendingUnionMerge mts'))
185189
186190-- | Test if a 'MergingTree' is \"obviously\" empty by virtue of its structure.
187191-- This is not the same as being empty due to a pending or ongoing merge
@@ -191,9 +195,9 @@ isStructurallyEmpty :: MonadMVar m => Ref (MergingTree m h) -> m Bool
191195isStructurallyEmpty (DeRef MergingTree {mergeState}) =
192196 isEmpty <$> readMVar mergeState
193197 where
194- isEmpty (PendingTreeMerge (PendingLevelMerge [] Nothing )) = True
195- isEmpty (PendingTreeMerge (PendingUnionMerge [] )) = True
196- isEmpty _ = False
198+ isEmpty (PendingTreeMerge (PendingLevelMerge prs Nothing )) = V. null prs
199+ isEmpty (PendingTreeMerge (PendingUnionMerge mts )) = V. null mts
200+ isEmpty _ = False
197201 -- It may also turn out to be useful to consider CompletedTreeMerge with
198202 -- a zero length runs as empty.
199203
0 commit comments