Skip to content

Commit e8a4307

Browse files
committed
Introduce a CastWeakBlobRef class for retrieveBlobs
This new class allows us to cast blob references inside the implementation of `retrieveBlobs` differently depending on the monad it is running in. The `IO` instance casts blob references the same way we did before the previous commit. This reverts the slight performance impact that the previous commit introduced by removing the `Typeable m` constraint on the `retrieveBlobs` function.
1 parent 1d44bef commit e8a4307

File tree

5 files changed

+48
-21
lines changed

5 files changed

+48
-21
lines changed

src/Database/LSMTree/Internal/BlobRef.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Database.LSMTree.Internal.BlobRef (
1717
, removeReferences
1818
, readBlob
1919
, readBlobIOOp
20+
, CastWeakBlobRef (..)
2021
) where
2122

2223
import Control.DeepSeq (NFData (..))
@@ -29,6 +30,7 @@ import qualified Control.RefCount as RC
2930
import Data.Coerce (coerce)
3031
import qualified Data.Primitive.ByteArray as P (MutableByteArray,
3132
newPinnedByteArray, unsafeFreezeByteArray)
33+
import Data.Typeable
3234
import qualified Data.Vector as V
3335
import Data.Word (Word32, Word64)
3436
import qualified Database.LSMTree.Internal.RawBytes as RB
@@ -186,3 +188,14 @@ readBlobIOOp buf bufoff
186188
(fromIntegral blobSpanOffset :: FS.FileOffset)
187189
buf (FS.BufferOffset bufoff)
188190
(fromIntegral blobSpanSize :: FS.ByteCount)
191+
192+
-- | A stronger alternative to 'cast', which can be used to cast /only/ the @h@
193+
-- parameter to 'WeakBlobRef'.
194+
class CastWeakBlobRef m where
195+
castWeakBlobRef ::
196+
(Typeable h, Typeable h')
197+
=> WeakBlobRef m h
198+
-> Maybe (WeakBlobRef m h')
199+
200+
instance CastWeakBlobRef IO where
201+
castWeakBlobRef = cast

src/Database/LSMTree/Normal.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ module Database.LSMTree.Normal (
8383
-- ** Blobs
8484
, BlobRef
8585
, retrieveBlobs
86+
, CheckBlobRefType
8687

8788
-- * Durability (snapshots)
8889
, SnapshotName
@@ -115,7 +116,7 @@ import Control.Exception (throw)
115116
import Control.Monad
116117
import Data.Bifunctor (Bifunctor (..))
117118
import Data.Kind (Type)
118-
import Data.Typeable (Proxy (..), cast)
119+
import Data.Typeable (Proxy (..))
119120
import qualified Data.Vector as V
120121
import Database.LSMTree.Common (BlobRef (BlobRef), IOLike, Range (..),
121122
SerialiseKey, SerialiseValue, Session, SnapshotName,
@@ -570,6 +571,7 @@ deletes = updates . fmap (,Delete)
570571
retrieveBlobs ::
571572
( IOLike m
572573
, SerialiseValue blob
574+
, CheckBlobRefType m
573575
)
574576
=> Session m
575577
-> V.Vector (BlobRef m blob)
@@ -578,10 +580,11 @@ retrieveBlobs (Internal.Session' sesh) refs =
578580
V.map Internal.deserialiseBlob <$>
579581
Internal.retrieveBlobs sesh (V.imap checkBlobRefType refs)
580582
where
581-
checkBlobRefType _ (BlobRef (Internal.WeakBlobRef (Internal.BlobRef ref a b)))
582-
| Just ref' <- cast ref = Internal.WeakBlobRef (Internal.BlobRef ref' a b)
583+
checkBlobRefType _ (BlobRef ref) | Just ref' <- Internal.castWeakBlobRef ref = ref'
583584
checkBlobRefType i _ = throw (Internal.ErrBlobRefInvalid i)
584585

586+
type CheckBlobRefType = Internal.CastWeakBlobRef
587+
585588
{-------------------------------------------------------------------------------
586589
Snapshots
587590
-------------------------------------------------------------------------------}

test/Database/LSMTree/Class/Normal.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class (IsSession (Session h)) => IsTableHandle h where
120120
retrieveBlobs ::
121121
( IOLike m
122122
, SerialiseValue blob
123+
, R.CheckBlobRefType m
123124
)
124125
=> proxy h
125126
-> Session h m

test/Test/Database/LSMTree/Class/Normal.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ retrieveBlobsTrav ::
135135
, IOLike m
136136
, SerialiseValue blob
137137
, Traversable t
138+
, R.CheckBlobRefType m
138139
)
139140
=> proxy h
140141
-> Session h m
@@ -153,6 +154,7 @@ lookupsWithBlobs :: forall h m k v blob.
153154
, SerialiseKey k
154155
, SerialiseValue v
155156
, SerialiseValue blob
157+
, R.CheckBlobRefType m
156158
)
157159
=> h m k v blob
158160
-> Session h m
@@ -168,6 +170,7 @@ rangeLookupWithBlobs :: forall h m k v blob.
168170
, SerialiseKey k
169171
, SerialiseValue v
170172
, SerialiseValue blob
173+
, R.CheckBlobRefType m
171174
)
172175
=> h m k v blob
173176
-> Session h m
@@ -183,6 +186,7 @@ readCursorWithBlobs :: forall h m k v blob proxy.
183186
, SerialiseKey k
184187
, SerialiseValue v
185188
, SerialiseValue blob
189+
, R.CheckBlobRefType m
186190
)
187191
=> proxy h
188192
-> Session h m
@@ -199,6 +203,7 @@ readCursorAllWithBlobs :: forall h m k v blob proxy.
199203
, SerialiseKey k
200204
, SerialiseValue v
201205
, SerialiseValue blob
206+
, R.CheckBlobRefType m
202207
)
203208
=> proxy h
204209
-> Session h m

test/Test/Database/LSMTree/Normal/StateMachine.hs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import Database.LSMTree.Extras (showPowersOf)
7272
import Database.LSMTree.Extras.Generators (KeyForIndexCompact)
7373
import Database.LSMTree.Extras.NoThunks (assertNoThunks)
7474
import Database.LSMTree.Internal (LSMTreeError (..))
75+
import qualified Database.LSMTree.Internal.BlobRef as Internal
7576
import qualified Database.LSMTree.Model.Normal.Session as Model
7677
import qualified Database.LSMTree.ModelIO.Normal as M
7778
import qualified Database.LSMTree.Normal as R
@@ -128,6 +129,13 @@ tests = testGroup "Normal.StateMachine" [
128129
labelledExamples :: IO ()
129130
labelledExamples = QC.labelledExamples $ Lockstep.Run.tagActions (Proxy @(ModelState R.TableHandle))
130131

132+
instance Arbitrary M.TableConfig where
133+
arbitrary :: Gen M.TableConfig
134+
arbitrary = pure M.TableConfig
135+
136+
deriving via AllowThunk (M.Session IO)
137+
instance NoThunks (M.Session IO)
138+
131139
propLockstep_ModelIOImpl ::
132140
Actions (Lockstep (ModelState M.TableHandle))
133141
-> QC.Property
@@ -181,8 +189,17 @@ propLockstep_ModelIOImpl =
181189
| otherwise
182190
= Nothing
183191

184-
deriving via AllowThunk (M.Session IO)
185-
instance NoThunks (M.Session IO)
192+
instance Arbitrary R.TableConfig where
193+
arbitrary :: Gen R.TableConfig
194+
arbitrary = pure $ R.TableConfig {
195+
R.confMergePolicy = R.MergePolicyLazyLevelling
196+
, R.confSizeRatio = R.Four
197+
, R.confWriteBufferAlloc = R.AllocNumEntries (R.NumEntries 30)
198+
, R.confBloomFilterAlloc = R.AllocFixed 10
199+
, R.confFencePointerIndex = R.CompactIndex
200+
, R.confDiskCachePolicy = R.DiskCacheNone
201+
, R.confMergeSchedule = R.OneShot
202+
}
186203

187204
propLockstep_RealImpl_RealFS_IO ::
188205
Actions (Lockstep (ModelState R.TableHandle))
@@ -230,6 +247,10 @@ propLockstep_RealImpl_MockFS_IO =
230247
mockfs <- atomically $ readTMVar fsVar
231248
assert (MockFS.numOpenHandles mockfs == 0) $ pure ()
232249

250+
instance Internal.CastWeakBlobRef (IOSim s) where
251+
castWeakBlobRef (Internal.WeakBlobRef (Internal.BlobRef ref a b)) =
252+
(\ref' -> Internal.WeakBlobRef (Internal.BlobRef ref' a b)) <$> cast ref
253+
233254
propLockstep_RealImpl_MockFS_IOSim ::
234255
Actions (Lockstep (ModelState R.TableHandle))
235256
-> QC.Property
@@ -281,22 +302,6 @@ createSystemTempDirectory prefix = do
281302
hasBlockIO <- ioHasBlockIO hasFS defaultIOCtxParams
282303
pure (tempDir, hasFS, hasBlockIO)
283304

284-
instance Arbitrary M.TableConfig where
285-
arbitrary :: Gen M.TableConfig
286-
arbitrary = pure M.TableConfig
287-
288-
instance Arbitrary R.TableConfig where
289-
arbitrary :: Gen R.TableConfig
290-
arbitrary = pure $ R.TableConfig {
291-
R.confMergePolicy = R.MergePolicyLazyLevelling
292-
, R.confSizeRatio = R.Four
293-
, R.confWriteBufferAlloc = R.AllocNumEntries (R.NumEntries 30)
294-
, R.confBloomFilterAlloc = R.AllocFixed 10
295-
, R.confFencePointerIndex = R.CompactIndex
296-
, R.confDiskCachePolicy = R.DiskCacheNone
297-
, R.confMergeSchedule = R.OneShot
298-
}
299-
300305
{-------------------------------------------------------------------------------
301306
Key and value types
302307
-------------------------------------------------------------------------------}

0 commit comments

Comments
 (0)