@@ -82,6 +82,7 @@ import Control.Concurrent.Class.MonadSTM.RWVar (RWVar)
8282import qualified Control.Concurrent.Class.MonadSTM.RWVar as RW
8383import Control.DeepSeq
8484import Control.Monad (forM , unless , void )
85+ import Control.Monad.Class.MonadAsync as Async
8586import Control.Monad.Class.MonadST (MonadST (.. ))
8687import Control.Monad.Class.MonadThrow
8788import Control.Monad.Primitive
@@ -105,9 +106,12 @@ import Database.LSMTree.Internal.Config
105106import qualified Database.LSMTree.Internal.Cursor as Cursor
106107import Database.LSMTree.Internal.Entry (Entry )
107108import Database.LSMTree.Internal.Lookup (ByteCountDiscrepancy ,
108- ResolveSerialisedValue , lookupsIO )
109+ ResolveSerialisedValue , lookupsIO ,
110+ lookupsIOWithoutWriteBuffer )
109111import Database.LSMTree.Internal.MergeSchedule
112+ import qualified Database.LSMTree.Internal.MergingRun as MR
110113import Database.LSMTree.Internal.MergingTree
114+ import qualified Database.LSMTree.Internal.MergingTree.Lookup as MT
111115import Database.LSMTree.Internal.Paths (SessionRoot (.. ),
112116 SnapshotMetaDataChecksumFile (.. ),
113117 SnapshotMetaDataFile (.. ), SnapshotName )
@@ -123,6 +127,7 @@ import Database.LSMTree.Internal.Serialise (SerialisedBlob (..),
123127import Database.LSMTree.Internal.Snapshot
124128import Database.LSMTree.Internal.Snapshot.Codec
125129import Database.LSMTree.Internal.UniqCounter
130+ import qualified Database.LSMTree.Internal.Vector as V
126131import qualified Database.LSMTree.Internal.WriteBuffer as WB
127132import qualified Database.LSMTree.Internal.WriteBufferBlobs as WBB
128133import qualified System.FS.API as FS
@@ -799,16 +804,48 @@ close t = do
799804 -> IO (V.Vector (Maybe (Entry SerialisedValue (WeakBlobRef IO h)))) #-}
800805-- | See 'Database.LSMTree.Normal.lookups'.
801806lookups ::
802- (MonadST m , MonadSTM m , MonadThrow m )
807+ (MonadAsync m , MonadMask m , MonadMVar m , MonadST m )
803808 => ResolveSerialisedValue
804809 -> V. Vector SerialisedKey
805810 -> Table m h
806811 -> m (V. Vector (Maybe (Entry SerialisedValue (WeakBlobRef m h ))))
807812lookups resolve ks t = do
808813 traceWith (tableTracer t) $ TraceLookups (V. length ks)
809814 withOpenTable t $ \ tEnv ->
810- RW. withReadAccess (tableContent tEnv) $ \ tableContent ->
811- let ! cache = tableCache tableContent in
815+ RW. withReadAccess (tableContent tEnv) $ \ tableContent -> do
816+ case tableUnionLevel tableContent of
817+ NoUnion -> regularLevelLookups tEnv tableContent
818+ Union tree -> do
819+ isStructurallyEmpty tree >>= \ case
820+ True -> regularLevelLookups tEnv tableContent
821+ False ->
822+ -- TODO: the blob refs returned from the tree can be invalidated
823+ -- by supplyUnionCredits or other operations on any table that
824+ -- shares merging runs or trees. We need to keep open the runs!
825+ -- This could be achieved by storing the LookupTree and only
826+ -- calling MT.releaseLookupTree later, when we are okay with
827+ -- invalidating the blob refs (similar to the LevelsCache).
828+ -- Lookups then use the cached tree, but when should we rebuild
829+ -- the tree? On each call to supplyUnionCredits?
830+ withActionRegistry $ \ reg -> do
831+ regularResult <-
832+ -- asynchronously, so tree lookup batches can already be
833+ -- submitted without waiting for the result.
834+ Async. async $ regularLevelLookups tEnv tableContent
835+ treeBatches <- MT. buildLookupTree reg tree
836+ treeResults <- forM treeBatches $ \ runs ->
837+ Async. async $ treeBatchLookups tEnv runs
838+ -- TODO: if regular levels are empty, don't add them to tree
839+ res <- MT. foldLookupTree resolve $
840+ MT. mkLookupNode MR. MergeLevel $ V. fromList
841+ [ MT. LookupBatch regularResult
842+ , treeResults
843+ ]
844+ MT. releaseLookupTree reg treeBatches
845+ return res
846+ where
847+ regularLevelLookups tEnv tableContent = do
848+ let ! cache = tableCache tableContent
812849 lookupsIO
813850 (tableHasBlockIO tEnv)
814851 (tableArenaManager t)
@@ -821,6 +858,17 @@ lookups resolve ks t = do
821858 (cachedKOpsFiles cache)
822859 ks
823860
861+ treeBatchLookups tEnv runs =
862+ lookupsIOWithoutWriteBuffer
863+ (tableHasBlockIO tEnv)
864+ (tableArenaManager t)
865+ resolve
866+ runs
867+ (V. mapStrict (\ (DeRef r) -> Run. runFilter r) runs)
868+ (V. mapStrict (\ (DeRef r) -> Run. runIndex r) runs)
869+ (V. mapStrict (\ (DeRef r) -> Run. runKOpsFile r) runs)
870+ ks
871+
824872{-# SPECIALISE rangeLookup ::
825873 ResolveSerialisedValue
826874 -> Range SerialisedKey
0 commit comments