Skip to content

Commit c202034

Browse files
authored
Merge pull request #548 from IntersectMBO/jdral/normal-union
`First` semigroup instead of `First` monoid for blob semantics
2 parents e71c634 + a01b035 commit c202034

File tree

9 files changed

+35
-36
lines changed

9 files changed

+35
-36
lines changed

prototypes/ScheduledMerges.hs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,6 @@ newtype Value = V Int
235235
resolveValue :: Value -> Value -> Value
236236
resolveValue (V x) (V y) = V (x + y)
237237

238-
resolveBlob :: Maybe Blob -> Maybe Blob -> Maybe Blob
239-
resolveBlob (Just b) _ = Just b
240-
resolveBlob Nothing mb = mb
241-
242238
newtype Blob = B Int
243239
deriving stock (Eq, Show)
244240

@@ -456,29 +452,30 @@ mergek t =
456452
. Map.unionsWith (if isUnion t then combineUnion else combine)
457453

458454
-- | Combines two entries that have been performed after another. Therefore, the
459-
-- newer one overwrites the old one (or modifies it for 'Mupsert').
455+
-- newer one overwrites the old one (or modifies it for 'Mupsert'). Only take a
456+
-- blob from the left entry.
460457
combine :: Op -> Op -> Op
461458
combine new_ old = case new_ of
462459
Insert{} -> new_
463460
Delete{} -> new_
464461
Mupsert v -> case old of
465-
Insert v' b -> Insert (resolveValue v v') b
462+
Insert v' _ -> Insert (resolveValue v v') Nothing
466463
Delete -> Insert v Nothing
467464
Mupsert v' -> Mupsert (resolveValue v v')
468465

469466
-- | Combines two entries of runs that have been 'union'ed together. If any one
470467
-- has a value, the result should have a value (represented by 'Insert'). If
471-
-- both have a value, these values get combined monoidally.
468+
-- both have a value, these values get combined monoidally. Only take a blob
469+
-- from the left entry.
472470
--
473471
-- See 'MergeUnion'.
474472
combineUnion :: Op -> Op -> Op
475473
combineUnion Delete old = old
476474
combineUnion new_ Delete = new_
477475
combineUnion (Mupsert v') (Mupsert v ) = Insert (resolveValue v' v) Nothing
478-
combineUnion (Mupsert v') (Insert v b) = Insert (resolveValue v' v) b
476+
combineUnion (Mupsert v') (Insert v _) = Insert (resolveValue v' v) Nothing
479477
combineUnion (Insert v' b') (Mupsert v) = Insert (resolveValue v' v) b'
480-
combineUnion (Insert v' b') (Insert v b) = Insert (resolveValue v' v)
481-
(resolveBlob b' b)
478+
combineUnion (Insert v' b') (Insert v _) = Insert (resolveValue v' v) b'
482479

483480
expectCompletedMergingRun :: HasCallStack => MergingRun t s -> ST s Run
484481
expectCompletedMergingRun (MergingRun _ ref) = do

prototypes/ScheduledMergesTestQLS.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import Data.Constraint (Dict (..))
88
import Data.Map.Strict (Map)
99
import qualified Data.Map.Strict as Map
1010
import Data.Maybe (fromJust)
11-
import Data.Monoid (First (..))
1211
import Data.Proxy
12+
import Data.Semigroup (First (..))
1313
import Prelude hiding (lookup)
1414

1515
import ScheduledMerges as LSM

src/Database/LSMTree/Internal.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,8 +1409,8 @@ matchBy eq (x0 :| xs) =
14091409
matchOne :: a -> Int -> a -> Either Int ()
14101410
matchOne x i y =
14111411
if (x `eq` y)
1412-
then Left i
1413-
else Right ()
1412+
then Right ()
1413+
else Left i
14141414

14151415
-- | Check that all tables in the session match. If so, return the matched
14161416
-- session. If there is a mismatch, return the list indices of the mismatching

src/Database/LSMTree/Internal/Entry.hs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,32 +96,34 @@ unNumEntries (NumEntries x) = x
9696
instance Semigroup v => Semigroup (Entry v b) where
9797
e1 <> e2 = combine (<>) e1 e2
9898

99-
-- | Given a value-merge function, combine entries
99+
-- | Given a value-merge function, combine entries. Only take a blob from the
100+
-- left entry.
100101
combine :: (v -> v -> v) -> Entry v b -> Entry v b -> Entry v b
101-
combine _ e@Delete _ = e
102-
combine _ e@Insert {} _ = e
103-
combine _ e@InsertWithBlob {} _ = e
104-
combine _ (Mupdate u) Delete = Insert u
105-
combine f (Mupdate u) (Insert v) = Insert (f u v)
106-
combine f (Mupdate u) (InsertWithBlob v blob) = InsertWithBlob (f u v) blob
107-
combine f (Mupdate u) (Mupdate v) = Mupdate (f u v)
102+
combine _ e@Delete _ = e
103+
combine _ e@Insert {} _ = e
104+
combine _ e@InsertWithBlob {} _ = e
105+
combine _ (Mupdate u) Delete = Insert u
106+
combine f (Mupdate u) (Insert v) = Insert (f u v)
107+
combine f (Mupdate u) (InsertWithBlob v _) = Insert (f u v)
108+
combine f (Mupdate u) (Mupdate v) = Mupdate (f u v)
108109

109110
-- | Combine two entries of runs that have been 'union'ed together. If any one
110111
-- has a value, the result should have a value (represented by 'Insert'). If
111-
-- both have a value, these values get combined monoidally.
112+
-- both have a value, these values get combined monoidally. Only take a blob
113+
-- from the left entry.
112114
combineUnion :: (v -> v -> v) -> Entry v b -> Entry v b -> Entry v b
113115
combineUnion f = go
114116
where
115117
go Delete e = e
116118
go e Delete = e
117119
go (Insert u) (Insert v) = Insert (f u v)
118-
go (Insert u) (InsertWithBlob v b) = InsertWithBlob (f u v) b
120+
go (Insert u) (InsertWithBlob v _) = Insert (f u v)
119121
go (Insert u) (Mupdate v) = Insert (f u v)
120122
go (InsertWithBlob u b) (Insert v) = InsertWithBlob (f u v) b
121123
go (InsertWithBlob u b) (InsertWithBlob v _) = InsertWithBlob (f u v) b
122124
go (InsertWithBlob u b) (Mupdate v) = InsertWithBlob (f u v) b
123125
go (Mupdate u) (Insert v) = Insert (f u v)
124-
go (Mupdate u) (InsertWithBlob v b) = InsertWithBlob (f u v) b
126+
go (Mupdate u) (InsertWithBlob v _) = Insert (f u v)
125127
go (Mupdate u) (Mupdate v) = Insert (f u v)
126128

127129
combineMaybe :: (v -> v -> v) -> Maybe (Entry v b) -> Maybe (Entry v b) -> Maybe (Entry v b)

src/Database/LSMTree/Internal/Merge.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ doStepsUnion Merge {..} requestedSteps = go 0
363363
-- Similar to 'handleMupdate' in 'stepsLevel', but here we have to combine
364364
-- all entries monoidally, so there are no obsolete/overwritten entries
365365
-- that we could skip.
366+
--
367+
-- TODO(optimisation): If mergeMappend is const (which happens when calling
368+
-- `union` on a non-monoidal table), we could skip all remaining entries for
369+
-- the key. Unfortunately, we can't inspect the function. This would require
370+
-- encoding it as something like `Const | Resolve (_ -> _ -> _)`.
366371
handleEntry !n !key !entry Readers.Drained = do
367372
-- no future entries, no previous entry to resolve, just write!
368373
writeReaderEntry mergeType mergeBuilder key entry

test/Database/LSMTree/Model/Table.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ import Data.List.NonEmpty (NonEmpty (..))
5151
import Data.Map (Map)
5252
import qualified Data.Map.Range as Map.R
5353
import qualified Data.Map.Strict as Map
54-
import Data.Monoid (First (..))
5554
import Data.Proxy (Proxy (Proxy))
55+
import Data.Semigroup (First (..))
5656
import qualified Data.Vector as V
5757
import Database.LSMTree (LookupResult (..), QueryResult (..),
5858
ResolveValue (..), Update (..))

test/Test/Database/LSMTree/Class.hs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,7 @@ prop_lookupUpdate h ups k v1 mb1 v2 = ioProperty $ do
591591
res <- lookupsWithBlobs tbl s (V.singleton k)
592592

593593
-- notice the order.
594-
return $ case mb1 of
595-
Nothing -> res === V.singleton (Found (resolve v2 v1))
596-
Just b1 -> res === V.singleton (FoundWithBlob (resolve v2 v1) b1)
594+
return $ res === V.singleton (Found (resolve v2 v1))
597595

598596
-------------------------------------------------------------------------------
599597
-- implement classic QC tests for monoidal table unions
@@ -629,8 +627,8 @@ prop_union h ups1 ups2 (V.fromList -> testKeys) = ioProperty $ do
629627
= r
630628
unionResult (Found v1) (Found v2)
631629
= Found (resolve v1 v2)
632-
unionResult (Found v1) (FoundWithBlob v2 b2)
633-
= FoundWithBlob (resolve v1 v2) b2
630+
unionResult (Found v1) (FoundWithBlob v2 _)
631+
= Found (resolve v1 v2)
634632

635633
unionResult r@(FoundWithBlob _ _) NotFound
636634
= r

test/Test/Database/LSMTree/Internal/Merge.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ prop_MergeUnion fs hbio stepSize (SmallList rds) =
170170
Entry.Mupdate v -> Just (v, Nothing)
171171
Entry.Delete -> Nothing
172172

173-
resolveValueAndBlob (v', Nothing) (v, b) = (mappendValues v' v, b)
174-
resolveValueAndBlob (v', Just b) (v, _) = (mappendValues v' v, Just b)
173+
resolveValueAndBlob (v', b') (v, _) = (mappendValues v' v, b')
175174

176175
-- | After merging for a few steps, we can prematurely abort the merge, which
177176
-- should clean up properly.

test/Test/Database/LSMTree/Model/Table.hs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import qualified Data.ByteString as BS
77
import qualified Data.Vector as V
88
import Database.LSMTree.Common
99
import Database.LSMTree.Model.Table (LookupResult (..), Table,
10-
Update (..), lookups, retrieveBlobs)
10+
Update (..), lookups)
1111
import qualified Database.LSMTree.Model.Table as Model
1212
import Database.LSMTree.Monoidal (ResolveValue (..),
1313
resolveDeserialised)
@@ -84,9 +84,7 @@ prop_upsertDef k v tbl =
8484
where
8585
tbl' = case toList (lookups (V.singleton k) tbl) of
8686
[Found v'] -> inserts (V.singleton (k, resolve v v', Nothing)) tbl
87-
[FoundWithBlob v' b'] ->
88-
let [b] = V.toList $ retrieveBlobs (V.singleton b') in
89-
inserts (V.singleton (k, resolve v v', Just b)) tbl
87+
[FoundWithBlob v' _] -> inserts (V.singleton (k, resolve v v', Nothing)) tbl
9088
_ -> inserts (V.singleton (k, v, Nothing)) tbl
9189

9290
-- | Different key inserts commute.

0 commit comments

Comments
 (0)