Skip to content

Commit a5a739d

Browse files
committed
Remove resolve-related functions from the D.L.I.Entry module.
These functions are only used in tests. Moreover, the tests can replace these functions by 'Semigroup' functions like 'sconcat'.
1 parent 57dede1 commit a5a739d

File tree

2 files changed

+48
-60
lines changed
  • src/Database/LSMTree/Internal
  • test/Test/Database/LSMTree/Internal

2 files changed

+48
-60
lines changed

src/Database/LSMTree/Internal/Entry.hs

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,11 @@ module Database.LSMTree.Internal.Entry (
88
-- * Value resolution/merging
99
, combine
1010
, combineMaybe
11-
, combinesMonoidal
12-
, combinesNormal
13-
, resolveEntriesNormal
14-
, resolveEntriesMonoidal
1511
) where
1612

1713
import Control.DeepSeq (NFData (..))
1814
import Data.Bifoldable (Bifoldable (..))
1915
import Data.Bifunctor (Bifunctor (..))
20-
import Data.List.NonEmpty (NonEmpty)
21-
import qualified Data.List.NonEmpty as NE
22-
import qualified Database.LSMTree.Internal.Monoidal as Monoidal
23-
import qualified Database.LSMTree.Internal.Normal as Normal
2416

2517
data Entry v blobref
2618
= Insert !v
@@ -88,6 +80,10 @@ unNumEntries (NumEntries x) = x
8880
Value resolution/merging
8981
-------------------------------------------------------------------------------}
9082

83+
-- | As long as values are a semigroup, an Entry is too
84+
instance Semigroup v => Semigroup (Entry v blob) where
85+
e1 <> e2 = combine (<>) e1 e2
86+
9187
-- | Given a value-merge function, combine entries
9288
combine :: (v -> v -> v) -> Entry v blobref -> Entry v blobref -> Entry v blobref
9389
combine _ e@Delete _ = e
@@ -102,24 +98,3 @@ combineMaybe :: (v -> v -> v) -> Maybe (Entry v blobref) -> Maybe (Entry v blobr
10298
combineMaybe _ e1 Nothing = e1
10399
combineMaybe _ Nothing e2 = e2
104100
combineMaybe f (Just e1) (Just e2) = Just $! combine f e1 e2
105-
106-
combinesMonoidal :: (v -> v -> v) -> NonEmpty (Entry v blob) -> Entry v blob
107-
combinesMonoidal f = foldr1 (combine f) -- short-circuit fold
108-
109-
combinesNormal :: NonEmpty (Entry v blob) -> Entry v blob
110-
combinesNormal = NE.head
111-
112-
-- | Returns 'Nothing' if the combined entries can not be mapped to an
113-
-- 'Normal.Update'.
114-
resolveEntriesNormal ::
115-
NonEmpty (Entry v blob)
116-
-> Maybe (Normal.Update v blob)
117-
resolveEntriesNormal _ = error "about to be removed"
118-
119-
-- | Returns 'Nothing' if the combined entries can not be mapped to an
120-
-- 'Monoidal.Update'.
121-
resolveEntriesMonoidal ::
122-
(v -> v -> v)
123-
-> NonEmpty (Entry v blob)
124-
-> Maybe (Monoidal.Update v)
125-
resolveEntriesMonoidal _ _ = error "about to be removed"

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

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ module Test.Database.LSMTree.Internal.Entry (tests) where
88

99
import Data.Coerce
1010
import Data.List.NonEmpty (NonEmpty)
11-
import qualified Data.List.NonEmpty as NE
1211
import Data.Semigroup
1312
import Database.LSMTree.Extras.Generators ()
1413
import Database.LSMTree.Internal.BlobRef
@@ -18,7 +17,6 @@ import qualified Database.LSMTree.Internal.Normal as Normal
1817
import Test.QuickCheck
1918
import Test.QuickCheck.Classes (semigroupLaws)
2019
import Test.Tasty
21-
import Test.Tasty.HUnit
2220
import Test.Tasty.QuickCheck (QuickCheckMaxSize (QuickCheckMaxSize),
2321
QuickCheckTests (QuickCheckTests), testProperty)
2422
import Test.Util.QC
@@ -30,49 +28,66 @@ tests = adjustOption (\_ -> QuickCheckTests 10000) $
3028
testClassLaws "EntrySG" $
3129
semigroupLaws (Proxy @(EntrySG (Sum Int) BlobSpanSG))
3230
, testClassLaws "NormalUpdateSG" $
33-
semigroupLaws (Proxy @(NormalUpdateSG (Sum Int) String))
31+
-- Note that we are using Unlawful here because mupserts /should/ not
32+
-- show up for normal updates.
33+
semigroupLaws (Proxy @(NormalUpdateSG (Unlawful Int) String))
3434
, testClassLaws "MonoidalUpdateSG" $
3535
semigroupLaws (Proxy @(MonoidalUpdateSG (Sum Int)))
3636
, testProperty "prop_resolveEntriesNormalSemantics" $
37-
prop_resolveEntriesNormalSemantics @Int @String
37+
-- Note that we are using Unlawful here because mupserts /should/ not
38+
-- show up for normal updates.
39+
prop_resolveEntriesNormalSemantics @(Unlawful Int) @String
3840
, testProperty "prop_resolveMonoidalSemantics" $
3941
prop_resolveMonoidalSemantics @(Sum Int)
40-
, testCase "example resolveEntriesNormal" $ do
41-
let es = [InsertWithBlob (2 :: Int) 'a', Insert 17]
42-
Just (Normal.Insert 2 (Just 'a')) @=?
43-
resolveEntriesNormal (NE.fromList es)
44-
, testCase "example resolveEntriesMonoidal" $ do
45-
let es = [Mupdate (Sum 11 :: Sum Int), Mupdate (Sum 5), Insert 1]
46-
Just (Monoidal.Insert (Sum 17)) @=?
47-
resolveEntriesMonoidal (<>) (NE.fromList es)
4842
]
4943

44+
-- | @resolve == fromEntry . resolve . toEntry@
5045
prop_resolveEntriesNormalSemantics ::
51-
(Show v, Show blob, Eq v, Eq blob)
46+
(Show v, Show blob, Eq v, Eq blob, Semigroup v)
5247
=> NonEmpty (Normal.Update v blob)
5348
-> Property
54-
prop_resolveEntriesNormalSemantics es = real === expected
55-
where expected = coerce (Just . foldr1 (<>) . fmap NormalUpdateSG $ es)
56-
real = resolveEntriesNormal (fmap updateToEntryNormal es)
49+
prop_resolveEntriesNormalSemantics es = expected === real
50+
where expected = Just . unNormalUpdateSG . sconcat . fmap NormalUpdateSG $ es
51+
real = entryToUpdateNormal (sconcat (fmap updateToEntryNormal es))
5752

53+
-- | @resolve == fromEntry . resolve . toEntry@
5854
prop_resolveMonoidalSemantics ::
5955
(Show v, Eq v, Semigroup v)
6056
=> NonEmpty (Monoidal.Update v) -> Property
61-
prop_resolveMonoidalSemantics es = real === expected
62-
where expected = coerce (Just . foldr1 (<>) . fmap MonoidalUpdateSG $ es)
63-
real = resolveEntriesMonoidal (<>) (fmap updateToEntryMonoidal es)
57+
prop_resolveMonoidalSemantics es = expected === real
58+
where expected = Just . unMonoidalUpdateSG . sconcat . fmap MonoidalUpdateSG $ es
59+
real = entryToUpdateMonoidal (sconcat (fmap updateToEntryMonoidal es))
60+
61+
{-------------------------------------------------------------------------------
62+
Types
63+
-------------------------------------------------------------------------------}
64+
65+
-- | A wrapper type with a 'Semigroup' instance that always throws an error.
66+
newtype Unlawful a = Unlawful a
67+
deriving stock (Show, Eq)
68+
deriving newtype Arbitrary
69+
70+
-- | A 'Semigroup' instance that always throws an error.
71+
instance Semigroup (Unlawful a) where
72+
_ <> _ = error "unlawful"
6473

6574
-- | Semigroup wrapper for 'Normal.Update'
6675
newtype NormalUpdateSG v blob = NormalUpdateSG (Normal.Update v blob)
6776
deriving stock (Show, Eq)
6877
deriving newtype (Arbitrary)
6978
deriving Semigroup via First (Normal.Update v blob)
7079

80+
unNormalUpdateSG :: NormalUpdateSG v b -> Normal.Update v b
81+
unNormalUpdateSG (NormalUpdateSG x) = x
82+
7183
-- | Semigroup wrapper for 'Monoidal.Update'
7284
newtype MonoidalUpdateSG v = MonoidalUpdateSG (Monoidal.Update v)
7385
deriving stock (Show, Eq)
7486
deriving newtype (Arbitrary)
7587

88+
unMonoidalUpdateSG :: MonoidalUpdateSG v -> Monoidal.Update v
89+
unMonoidalUpdateSG (MonoidalUpdateSG x) = x
90+
7691
instance Semigroup v => Semigroup (MonoidalUpdateSG v) where
7792
(<>) = coerce $ \upd1 upd2 -> case (upd1 :: Monoidal.Update v, upd2) of
7893
(e1@Monoidal.Delete , _ ) -> e1
@@ -81,24 +96,22 @@ instance Semigroup v => Semigroup (MonoidalUpdateSG v) where
8196
(Monoidal.Mupsert v1 , Monoidal.Insert v2) -> Monoidal.Insert (v1 <> v2)
8297
(Monoidal.Mupsert v1 , Monoidal.Mupsert v2) -> Monoidal.Mupsert (v1 <> v2)
8398

84-
-- | Semigroup wrapper for Entry
8599
newtype EntrySG v blob = EntrySG (Entry v blob)
86100
deriving stock (Show, Eq)
87-
88-
-- | As long as values are a semigroup, an Entry is too
89-
instance Semigroup v => Semigroup (EntrySG v blob) where
90-
EntrySG e1 <> EntrySG e2 = EntrySG (combine (<>) e1 e2)
101+
deriving newtype Semigroup
91102

92103
instance (Arbitrary v, Arbitrary blob) => Arbitrary (EntrySG v blob) where
93104
arbitrary = arbitrary2
94105
shrink = shrink2
95106

107+
-- | We do not use the @'Arbitrary' 'Entry'@ instance here, because we want to
108+
-- generate each constructor with equal probability.
96109
instance Arbitrary2 EntrySG where
97110
liftArbitrary2 genVal genBlob = EntrySG <$> frequency
98111
[ (1, Insert <$> genVal)
99-
, (1, InsertWithBlob <$> genVal <*> genBlob)
100-
, (1, Mupdate <$> genVal)
101-
, (1, pure Delete)
112+
, (1, InsertWithBlob <$> genVal <*> genBlob)
113+
, (1, Mupdate <$> genVal)
114+
, (1, pure Delete)
102115
]
103116

104117
liftShrink2 shrinkVal shrinkBlob = coerce $ \case
@@ -127,8 +140,8 @@ updateToEntryNormal = \case
127140
Normal.Insert v (Just b) -> InsertWithBlob v b
128141
Normal.Delete -> Delete
129142

130-
_entryToUpdateNormal :: Entry v blob -> Maybe (Normal.Update v blob)
131-
_entryToUpdateNormal = \case
143+
entryToUpdateNormal :: Entry v blob -> Maybe (Normal.Update v blob)
144+
entryToUpdateNormal = \case
132145
Insert v -> Just (Normal.Insert v Nothing)
133146
InsertWithBlob v b -> Just (Normal.Insert v (Just b))
134147
Mupdate _ -> Nothing
@@ -140,8 +153,8 @@ updateToEntryMonoidal = \case
140153
Monoidal.Mupsert v -> Mupdate v
141154
Monoidal.Delete -> Delete
142155

143-
_entryToUpdateMonoidal :: Entry v blob -> Maybe (Monoidal.Update v)
144-
_entryToUpdateMonoidal = \case
156+
entryToUpdateMonoidal :: Entry v blob -> Maybe (Monoidal.Update v)
157+
entryToUpdateMonoidal = \case
145158
Insert v -> Just (Monoidal.Insert v)
146159
InsertWithBlob _ _ -> Nothing
147160
Mupdate v -> Just (Monoidal.Mupsert v)

0 commit comments

Comments
 (0)