Skip to content

Commit f52293b

Browse files
authored
Merge pull request #491 from IntersectMBO/jdral/n-way-unions-boilerplate
Boilerplate for the implementation of n-way unions
2 parents df2877a + cb6827e commit f52293b

File tree

12 files changed

+287
-105
lines changed

12 files changed

+287
-105
lines changed

src-extras/Database/LSMTree/Extras/NoThunks.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,16 @@ deriving anyclass instance (NoThunksIOLike m, Typeable m, Typeable h, Typeable (
125125
deriving stock instance Generic (Internal.Table m h)
126126
-- | Does not check 'NoThunks' for the 'Internal.Session' that this
127127
-- 'Internal.Table' belongs to.
128-
deriving anyclass instance (NoThunksIOLike m, Typeable m, Typeable h, Typeable (PrimState m))
129-
=> NoThunks (Internal.Table m h)
128+
deriving via AllowThunksIn '["tableSession"] (Table m h)
129+
instance (NoThunksIOLike m, Typeable m, Typeable h, Typeable (PrimState m))
130+
=> NoThunks (Internal.Table m h)
130131

131132
deriving stock instance Generic (TableState m h)
132133
deriving anyclass instance (NoThunksIOLike m, Typeable m, Typeable h, Typeable (PrimState m))
133134
=> NoThunks (TableState m h)
134135

135136
deriving stock instance Generic (TableEnv m h)
136-
deriving via AllowThunksIn ["tableSession", "tableSessionEnv"] (TableEnv m h)
137+
deriving via AllowThunksIn '["tableSessionEnv"] (TableEnv m h)
137138
instance (NoThunksIOLike m, Typeable m, Typeable h, Typeable (PrimState m))
138139
=> NoThunks (TableEnv m h)
139140

src/Database/LSMTree.hs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE MagicHash #-}
2+
13
-- | This module is experimental. It is mainly used for testing purposes.
24
--
35
-- See the 'Normal' and 'Monoidal' modules for documentation.
@@ -105,7 +107,8 @@ import Control.Monad.Class.MonadThrow
105107
import Data.Bifunctor (Bifunctor (..))
106108
import Data.Coerce (coerce)
107109
import Data.Kind (Type)
108-
import Data.Typeable (Proxy (..), eqT, type (:~:) (Refl))
110+
import Data.List.NonEmpty (NonEmpty (..))
111+
import Data.Typeable (Proxy (..), Typeable, eqT, type (:~:) (Refl))
109112
import qualified Data.Vector as V
110113
import Database.LSMTree.Common (BlobRef (BlobRef), IOLike, Range (..),
111114
SerialiseKey, SerialiseValue, Session, SnapshotName,
@@ -122,6 +125,7 @@ import qualified Database.LSMTree.Internal.Vector as V
122125
import Database.LSMTree.Monoidal (ResolveValue (..),
123126
resolveDeserialised, resolveValueAssociativity,
124127
resolveValueValidOutput)
128+
import GHC.Exts (Proxy#, proxy#)
125129

126130
{-------------------------------------------------------------------------------
127131
Tables
@@ -518,28 +522,38 @@ duplicate (Internal.Table' t) = Internal.Table' <$!> Internal.duplicate t
518522
-------------------------------------------------------------------------------}
519523

520524
{-# SPECIALISE union ::
521-
ResolveValue v
522-
=> Table IO k v b
525+
Table IO k v b
523526
-> Table IO k v b
524527
-> IO (Table IO k v b) #-}
525528
union :: forall m k v b.
526-
( IOLike m
527-
, ResolveValue v
528-
)
529+
IOLike m
529530
=> Table m k v b
530531
-> Table m k v b
531532
-> m (Table m k v b)
532-
union = error "union: not yet implemented" $ union @m @k @v @b
533+
union t1 t2 = unions $ t1 :| [t2]
533534

534535
{-# SPECIALISE unions ::
535-
ResolveValue v
536-
=> V.Vector (Table IO k v b)
536+
NonEmpty (Table IO k v b)
537537
-> IO (Table IO k v b) #-}
538538
unions :: forall m k v b.
539-
(IOLike m, ResolveValue v)
540-
=> V.Vector (Table m k v b)
539+
IOLike m
540+
=> NonEmpty (Table m k v b)
541541
-> m (Table m k v b)
542-
unions = error "unions: not yet implemented" $ unions @m @k @v
542+
unions (t :| ts) =
543+
case t of
544+
Internal.Table' (t' :: Internal.Table m h) -> do
545+
ts' <- zipWithM (checkTableType (proxy# @h)) [1..] ts
546+
Internal.Table' <$> Internal.unions (t' :| ts')
547+
where
548+
checkTableType ::
549+
forall h. Typeable h
550+
=> Proxy# h
551+
-> Int
552+
-> Table m k v b
553+
-> m (Internal.Table m h)
554+
checkTableType _ i (Internal.Table' (t' :: Internal.Table m h'))
555+
| Just Refl <- eqT @h @h' = pure t'
556+
| otherwise = throwIO (Internal.ErrUnionsTableTypeMismatch 0 i)
543557

544558
{-------------------------------------------------------------------------------
545559
Monoidal value resolution

0 commit comments

Comments
 (0)