Skip to content

Commit 298b734

Browse files
committed
Start using the new snapshot metadata encoders/decoders
1 parent 733b8f7 commit 298b734

File tree

9 files changed

+66
-54
lines changed

9 files changed

+66
-54
lines changed

bench/macro/lsm-tree-bench-wp8.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ runOptsP = pure RunOpts
229229
<*> O.switch (O.long "pipelined" <> O.help "Use pipelined mode")
230230
<*> O.switch (O.long "lookup-only" <> O.help "Use lookup only mode")
231231

232+
deriving stock instance Read LSM.DiskCachePolicy
233+
deriving stock instance Read LSM.BloomFilterAlloc
234+
deriving stock instance Read LSM.NumEntries
235+
232236
-------------------------------------------------------------------------------
233237
-- measurements
234238
-------------------------------------------------------------------------------

src/Database/LSMTree/Internal.hs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ module Database.LSMTree.Internal (
6666
, duplicate
6767
) where
6868

69+
import Codec.CBOR.Read
6970
import Control.Concurrent.Class.MonadMVar.Strict
7071
import Control.Concurrent.Class.MonadSTM (MonadSTM (..))
7172
import Control.Concurrent.Class.MonadSTM.RWVar (RWVar)
@@ -79,7 +80,6 @@ import Control.Monad.Primitive
7980
import Control.TempRegistry
8081
import Control.Tracer
8182
import Data.Arena (ArenaManager, newArenaManager)
82-
import qualified Data.ByteString.Char8 as BSC
8383
import Data.Char (isNumber)
8484
import Data.Foldable
8585
import Data.Functor.Compose (Compose (..))
@@ -119,7 +119,6 @@ import qualified System.FS.API as FS
119119
import System.FS.API (FsError, FsErrorPath (..), FsPath, Handle,
120120
HasFS)
121121
import qualified System.FS.API.Lazy as FS
122-
import qualified System.FS.API.Strict as FS
123122
import qualified System.FS.BlockIO.API as FS
124123
import System.FS.BlockIO.API (HasBlockIO)
125124

@@ -166,6 +165,9 @@ instance NFData (MonoidalCursor m k v) where
166165
-------------------------------------------------------------------------------}
167166

168167
-- TODO: give this a nicer Show instance.
168+
--
169+
-- TODO: the snapshot-related errors could be put in a separate type, since each
170+
-- gets a SnapshotName.
169171
data LSMTreeError =
170172
SessionDirDoesNotExist FsErrorPath
171173
-- | The session directory is already locked
@@ -186,7 +188,15 @@ data LSMTreeError =
186188
| ErrCursorClosed
187189
| ErrSnapshotExists SnapshotName
188190
| ErrSnapshotNotExists SnapshotName
189-
| ErrSnapshotWrongType SnapshotName
191+
| ErrSnapshotDeserialiseFailure DeserialiseFailure SnapshotName
192+
| ErrSnapshotWrongTableType
193+
SnapshotName
194+
SnapshotTableType -- ^ Expected type
195+
SnapshotTableType -- ^ Actual type
196+
| ErrSnapshotWrongLabel
197+
SnapshotName
198+
SnapshotLabel -- ^ Expected label
199+
SnapshotLabel -- ^ Actual label
190200
-- | Something went wrong during batch lookups.
191201
| ErrLookup ByteCountDiscrepancy
192202
-- | A 'BlobRef' used with 'retrieveBlobs' was invalid.
@@ -1081,6 +1091,7 @@ readCursorWhile resolve keyIsWanted n Cursor {..} fromEntry = do
10811091
ResolveSerialisedValue
10821092
-> SnapshotName
10831093
-> SnapshotLabel
1094+
-> SnapshotTableType
10841095
-> Table IO h
10851096
-> IO Int #-}
10861097
-- | See 'Database.LSMTree.Normal.snapshot''.
@@ -1089,9 +1100,10 @@ snapshot ::
10891100
=> ResolveSerialisedValue
10901101
-> SnapshotName
10911102
-> SnapshotLabel
1103+
-> SnapshotTableType
10921104
-> Table m h
10931105
-> m Int
1094-
snapshot resolve snap label t = do
1106+
snapshot resolve snap label tableType t = do
10951107
traceWith (tableTracer t) $ TraceSnapshot snap
10961108
let conf = tableConfig t
10971109
withOpenTable t $ \thEnv -> do
@@ -1129,19 +1141,20 @@ snapshot resolve snap label t = do
11291141
-- consistent.
11301142

11311143
snappedLevels <- snapLevels (tableLevels content)
1132-
let snapContents = BSC.pack $ show (label, snappedLevels, tableConfig t)
1144+
let snapContents = encodeSnapshotMetaData (SnapshotMetaData label tableType (tableConfig t) snappedLevels)
11331145

11341146
FS.withFile
11351147
(tableHasFS thEnv)
11361148
snapPath
11371149
(FS.WriteMode FS.MustBeNew) $ \h ->
1138-
void $ FS.hPutAllStrict (tableHasFS thEnv) h snapContents
1150+
void $ FS.hPutAll (tableHasFS thEnv) h snapContents
11391151

11401152
pure $! numSnapRuns snappedLevels
11411153

11421154
{-# SPECIALISE open ::
11431155
Session IO h
11441156
-> SnapshotLabel
1157+
-> SnapshotTableType
11451158
-> TableConfigOverride
11461159
-> SnapshotName
11471160
-> ResolveSerialisedValue
@@ -1151,11 +1164,12 @@ open ::
11511164
(MonadFix m, MonadMask m, MonadMVar m, MonadST m, MonadSTM m)
11521165
=> Session m h
11531166
-> SnapshotLabel -- ^ Expected label
1167+
-> SnapshotTableType -- ^ Expected table type
11541168
-> TableConfigOverride -- ^ Optional config override
11551169
-> SnapshotName
11561170
-> ResolveSerialisedValue
11571171
-> m (Table m h)
1158-
open sesh label override snap resolve = do
1172+
open sesh label tableType override snap resolve = do
11591173
traceWith (sessionTracer sesh) $ TraceOpenSnapshot snap override
11601174
withOpenSession sesh $ \seshEnv -> do
11611175
withTempRegistry $ \reg -> do
@@ -1169,8 +1183,18 @@ open sesh label override snap resolve = do
11691183
snapPath
11701184
FS.ReadMode $ \h ->
11711185
FS.hGetAll (sessionHasFS seshEnv) h
1172-
let (label', snappedLevels, conf) = read $ BSC.unpack $ BSC.toStrict $ bs
1173-
unless (label == label') $ throwIO (ErrSnapshotWrongType snap)
1186+
1187+
snapMetaData <- case decodeSnapshotMetaData bs of
1188+
Left e -> throwIO (ErrSnapshotDeserialiseFailure e snap)
1189+
Right x -> pure x
1190+
let SnapshotMetaData label' tableType' conf snappedLevels = snapMetaData
1191+
1192+
unless (tableType == tableType') $
1193+
throwIO (ErrSnapshotWrongTableType snap tableType tableType')
1194+
1195+
unless (label == label') $
1196+
throwIO (ErrSnapshotWrongLabel snap label label')
1197+
11741198
let conf' = applyOverride override conf
11751199
am <- newArenaManager
11761200
blobpath <- Paths.tableBlobPath (sessionRoot seshEnv) <$>

src/Database/LSMTree/Internal/Config.hs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
-- TODO: this should be removed once we have proper snapshotting with proper
2-
-- persistence of the config to disk.
3-
{-# OPTIONS_GHC -Wno-orphans #-}
4-
51
module Database.LSMTree.Internal.Config (
62
LevelNo (..)
73
-- * Table configuration
@@ -359,7 +355,7 @@ data DiskCachePolicy =
359355
-- Use this policy if expected access pattern for the table has poor
360356
-- spatial or temporal locality, such as uniform random access.
361357
| DiskCacheNone
362-
deriving stock (Eq, Show, Read)
358+
deriving stock (Eq, Show)
363359

364360
instance NFData DiskCachePolicy where
365361
rnf DiskCacheAll = ()
@@ -403,7 +399,7 @@ data MergeSchedule =
403399
-- merges are fully completed in time for when new merges are started on the
404400
-- same level.
405401
| Incremental
406-
deriving stock (Eq, Show, Read)
402+
deriving stock (Eq, Show)
407403

408404
instance NFData MergeSchedule where
409405
rnf OneShot = ()

src/Database/LSMTree/Internal/Snapshot.hs

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
-- TODO: remove once we properly implement snapshots
2-
{-# OPTIONS_GHC -Wno-orphans #-}
3-
41
module Database.LSMTree.Internal.Snapshot (
52
-- * Versioning
63
SnapshotVersion (..)
@@ -142,10 +139,10 @@ isCompatible otherVersion = do
142139

143140
-- | Custom text to include in a snapshot file
144141
newtype SnapshotLabel = SnapshotLabel Text
145-
deriving stock (Show, Eq, Read)
142+
deriving stock (Show, Eq)
146143

147144
data SnapshotTableType = SnapNormalTable | SnapMonoidalTable
148-
deriving stock (Show, Eq, Read)
145+
deriving stock (Show, Eq)
149146

150147
data SnapshotMetaData = SnapshotMetaData {
151148
-- | Custom, user-supplied text that is included in the metadata.
@@ -195,22 +192,22 @@ data SnapLevel = SnapLevel {
195192
snapIncomingRuns :: !SnapMergingRun
196193
, snapResidentRuns :: !(V.Vector RunNumber)
197194
}
198-
deriving stock (Show, Eq, Read)
195+
deriving stock (Show, Eq)
199196

200197
data SnapMergingRun =
201198
SnapMergingRun !MergePolicyForLevel !NumRuns !SnapMergingRunState
202199
| SnapSingleRun !RunNumber
203-
deriving stock (Show, Eq, Read)
200+
deriving stock (Show, Eq)
204201

205202
data SnapMergingRunState =
206203
SnapCompletedMerge !RunNumber
207204
| SnapOngoingMerge !(V.Vector RunNumber) !TotalCredits !Merge.Level
208-
deriving stock (Show, Eq, Read)
205+
deriving stock (Show, Eq)
209206

210207
-- | The total number of supplied credits. This total is used on snapshot load
211208
-- to restore merging work that was lost when the snapshot was created.
212209
newtype TotalCredits = TotalCredits Int
213-
deriving stock (Show, Eq, Read)
210+
deriving stock (Show, Eq)
214211

215212
{-------------------------------------------------------------------------------
216213
Conversion to snapshot format
@@ -347,27 +344,6 @@ openLevels reg hfs hbio conf@TableConfig{..} uc sessionRoot resolve levels =
347344
Nothing -> error "openLevels: merges can not be empty"
348345
Just m -> pure (Just totalCredits, OngoingMerge rs totalStepsVar totalCreditsVar m)
349346

350-
{-------------------------------------------------------------------------------
351-
Levels
352-
-------------------------------------------------------------------------------}
353-
354-
deriving stock instance Read NumRuns
355-
deriving stock instance Read MergePolicyForLevel
356-
deriving newtype instance Read RunNumber
357-
deriving stock instance Read Merge.Level
358-
359-
{-------------------------------------------------------------------------------
360-
Config
361-
-------------------------------------------------------------------------------}
362-
363-
deriving stock instance Read TableConfig
364-
deriving stock instance Read WriteBufferAlloc
365-
deriving stock instance Read NumEntries
366-
deriving stock instance Read SizeRatio
367-
deriving stock instance Read MergePolicy
368-
deriving stock instance Read BloomFilterAlloc
369-
deriving stock instance Read FencePointerIndex
370-
371347
{-------------------------------------------------------------------------------
372348
Encoding and decoding
373349
-------------------------------------------------------------------------------}

src/Database/LSMTree/Monoidal.hs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ snapshot :: forall m k v.
559559
-> Table m k v
560560
-> m ()
561561
snapshot snap (Internal.MonoidalTable t) =
562-
void $ Internal.snapshot (resolve @v Proxy) snap label t
562+
void $ Internal.snapshot (resolve @v Proxy) snap label Internal.SnapMonoidalTable t
563563
where
564564
label = Internal.SnapshotLabel $ Common.makeSnapshotLabel (Proxy @(k, v))
565565

@@ -603,7 +603,14 @@ open :: forall m k v.
603603
-> SnapshotName
604604
-> m (Table m k v)
605605
open (Internal.Session' sesh) override snap =
606-
Internal.MonoidalTable <$> Internal.open sesh label override snap (resolve @v Proxy)
606+
Internal.MonoidalTable <$>
607+
Internal.open
608+
sesh
609+
label
610+
Internal.SnapMonoidalTable
611+
override
612+
snap
613+
(resolve @v Proxy)
607614
where
608615
label = Internal.SnapshotLabel $ Common.makeSnapshotLabel (Proxy @(k, v))
609616

src/Database/LSMTree/Normal.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,8 @@ snapshot :: forall m k v blob.
685685
=> SnapshotName
686686
-> Table m k v blob
687687
-> m ()
688-
snapshot snap (Internal.NormalTable t) = void $ Internal.snapshot const snap label t
688+
snapshot snap (Internal.NormalTable t) =
689+
void $ Internal.snapshot const snap label Internal.SnapNormalTable t
689690
where
690691
label = Internal.SnapshotLabel $ Common.makeSnapshotLabel (Proxy @(k, v, blob))
691692

@@ -732,7 +733,7 @@ open :: forall m k v blob.
732733
-> SnapshotName
733734
-> m (Table m k v blob)
734735
open (Internal.Session' sesh) override snap =
735-
Internal.NormalTable <$!> Internal.open sesh label override snap const
736+
Internal.NormalTable <$!> Internal.open sesh label Internal.SnapNormalTable override snap const
736737
where
737738
label = Internal.SnapshotLabel $ Common.makeSnapshotLabel (Proxy @(k, v, blob))
738739

test/Test/Database/LSMTree/Internal.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import Database.LSMTree.Internal.Entry
2929
import Database.LSMTree.Internal.MergeSchedule
3030
import Database.LSMTree.Internal.Paths (mkSnapshotName)
3131
import Database.LSMTree.Internal.Serialise
32-
import Database.LSMTree.Internal.Snapshot (SnapshotLabel (..))
32+
import Database.LSMTree.Internal.Snapshot (SnapshotLabel (..),
33+
SnapshotTableType (..))
3334
import qualified System.FS.API as FS
3435
import qualified Test.Database.LSMTree.Internal.Lookup as Test
3536
import Test.Database.LSMTree.Internal.Lookup
@@ -174,8 +175,8 @@ prop_interimOpenTable dat = ioProperty $
174175
withTable sesh conf $ \t -> do
175176
updates const upds t
176177
let snap = fromMaybe (error "invalid name") $ mkSnapshotName "snap"
177-
numRunsSnapped <- snapshot const snap (SnapshotLabel "someLabel") t
178-
t' <- open sesh (SnapshotLabel "someLabel") configNoOverride snap const
178+
numRunsSnapped <- snapshot const snap (SnapshotLabel "someLabel") SnapNormalTable t
179+
t' <- open sesh (SnapshotLabel "someLabel") SnapNormalTable configNoOverride snap const
179180
lhs <- fetchBlobs hfs =<< lookups const ks t
180181
rhs <- fetchBlobs hfs =<< lookups const ks t'
181182
-- We must fetch blobs because comparing blob references is meaningless

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ realHandler = Handler $ pure . handler'
341341
handler' ErrCursorClosed = Just Model.ErrCursorClosed
342342
handler' (ErrSnapshotNotExists _snap) = Just Model.ErrSnapshotDoesNotExist
343343
handler' (ErrSnapshotExists _snap) = Just Model.ErrSnapshotExists
344-
handler' (ErrSnapshotWrongType _snap) = Just Model.ErrSnapshotWrongType
344+
handler' ErrSnapshotWrongTableType{} = Just Model.ErrSnapshotWrongType
345345
handler' (ErrBlobRefInvalid _) = Just Model.ErrBlobRefInvalidated
346346
handler' _ = Nothing
347347

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import qualified Data.Vector as V
1313
import Data.Word
1414
import qualified System.FS.API as FS
1515

16+
import Database.LSMTree.Internal.Snapshot (SnapshotLabel (..))
1617
import Database.LSMTree.Normal as R
1718

1819
import Control.Exception (Exception, try)
@@ -132,7 +133,9 @@ unit_snapshots =
132133
assertException (ErrSnapshotExists snap1) $
133134
snapshot snap1 tbl
134135

135-
assertException (ErrSnapshotWrongType snap1) $ do
136+
assertException (ErrSnapshotWrongLabel snap1
137+
(SnapshotLabel "Key2 Value2 Blob2")
138+
(SnapshotLabel "Key1 Value1 Blob1")) $ do
136139
_ <- open @_ @Key2 @Value2 @Blob2 sess configNoOverride snap1
137140
return ()
138141

0 commit comments

Comments
 (0)