Skip to content

Commit 14950a7

Browse files
authored
Merge pull request #443 from IntersectMBO/jdral/snapshot-encode-decode
Encoding and decoding of snapshot metadata as CBOR
2 parents cad1fe7 + 5ba267d commit 14950a7

File tree

12 files changed

+791
-103
lines changed

12 files changed

+791
-103
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
-------------------------------------------------------------------------------

lsm-tree.cabal

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ library
166166
, base >=4.14 && <4.21
167167
, bitvec ^>=1.1
168168
, bytestring ^>=0.11.4.0 || ^>=0.12.1.0
169+
, cborg ^>=0.2.10.0
169170
, containers ^>=0.6 || ^>=0.7
170171
, contra-tracer ^>=0.2
171172
, crc32c ^>=0.2.1
@@ -367,6 +368,7 @@ test-suite lsm-tree-test
367368
Test.Database.LSMTree.Internal.RunReaders
368369
Test.Database.LSMTree.Internal.Serialise
369370
Test.Database.LSMTree.Internal.Serialise.Class
371+
Test.Database.LSMTree.Internal.Snapshot
370372
Test.Database.LSMTree.Internal.Vector
371373
Test.Database.LSMTree.Internal.Vector.Growing
372374
Test.Database.LSMTree.Model.Table
@@ -388,6 +390,7 @@ test-suite lsm-tree-test
388390
, base
389391
, bitvec
390392
, bytestring
393+
, cborg
391394
, constraints
392395
, containers
393396
, contra-tracer
@@ -426,6 +429,7 @@ test-suite lsm-tree-test
426429
, tasty-hunit
427430
, tasty-quickcheck
428431
, temporary
432+
, text
429433
, these
430434
, transformers
431435
, vector

src/Database/LSMTree/Internal.hs

Lines changed: 30 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

@@ -186,7 +185,15 @@ data LSMTreeError =
186185
| ErrCursorClosed
187186
| ErrSnapshotExists SnapshotName
188187
| ErrSnapshotNotExists SnapshotName
189-
| ErrSnapshotWrongType SnapshotName
188+
| ErrSnapshotDeserialiseFailure DeserialiseFailure SnapshotName
189+
| ErrSnapshotWrongTableType
190+
SnapshotName
191+
SnapshotTableType -- ^ Expected type
192+
SnapshotTableType -- ^ Actual type
193+
| ErrSnapshotWrongLabel
194+
SnapshotName
195+
SnapshotLabel -- ^ Expected label
196+
SnapshotLabel -- ^ Actual label
190197
-- | Something went wrong during batch lookups.
191198
| ErrLookup ByteCountDiscrepancy
192199
-- | A 'BlobRef' used with 'retrieveBlobs' was invalid.
@@ -1081,6 +1088,7 @@ readCursorWhile resolve keyIsWanted n Cursor {..} fromEntry = do
10811088
ResolveSerialisedValue
10821089
-> SnapshotName
10831090
-> SnapshotLabel
1091+
-> SnapshotTableType
10841092
-> Table IO h
10851093
-> IO Int #-}
10861094
-- | See 'Database.LSMTree.Normal.snapshot''.
@@ -1089,9 +1097,10 @@ snapshot ::
10891097
=> ResolveSerialisedValue
10901098
-> SnapshotName
10911099
-> SnapshotLabel
1100+
-> SnapshotTableType
10921101
-> Table m h
10931102
-> m Int
1094-
snapshot resolve snap label t = do
1103+
snapshot resolve snap label tableType t = do
10951104
traceWith (tableTracer t) $ TraceSnapshot snap
10961105
let conf = tableConfig t
10971106
withOpenTable t $ \thEnv -> do
@@ -1129,19 +1138,20 @@ snapshot resolve snap label t = do
11291138
-- consistent.
11301139

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

11341143
FS.withFile
11351144
(tableHasFS thEnv)
11361145
snapPath
11371146
(FS.WriteMode FS.MustBeNew) $ \h ->
1138-
void $ FS.hPutAllStrict (tableHasFS thEnv) h snapContents
1147+
void $ FS.hPutAll (tableHasFS thEnv) h snapContents
11391148

11401149
pure $! numSnapRuns snappedLevels
11411150

11421151
{-# SPECIALISE open ::
11431152
Session IO h
11441153
-> SnapshotLabel
1154+
-> SnapshotTableType
11451155
-> TableConfigOverride
11461156
-> SnapshotName
11471157
-> ResolveSerialisedValue
@@ -1151,11 +1161,12 @@ open ::
11511161
(MonadFix m, MonadMask m, MonadMVar m, MonadST m, MonadSTM m)
11521162
=> Session m h
11531163
-> SnapshotLabel -- ^ Expected label
1164+
-> SnapshotTableType -- ^ Expected table type
11541165
-> TableConfigOverride -- ^ Optional config override
11551166
-> SnapshotName
11561167
-> ResolveSerialisedValue
11571168
-> m (Table m h)
1158-
open sesh label override snap resolve = do
1169+
open sesh label tableType override snap resolve = do
11591170
traceWith (sessionTracer sesh) $ TraceOpenSnapshot snap override
11601171
withOpenSession sesh $ \seshEnv -> do
11611172
withTempRegistry $ \reg -> do
@@ -1169,8 +1180,18 @@ open sesh label override snap resolve = do
11691180
snapPath
11701181
FS.ReadMode $ \h ->
11711182
FS.hGetAll (sessionHasFS seshEnv) h
1172-
let (label', snappedLevels, conf) = read $ BSC.unpack $ BSC.toStrict $ bs
1173-
unless (label == label') $ throwIO (ErrSnapshotWrongType snap)
1183+
1184+
snapMetaData <- case decodeSnapshotMetaData bs of
1185+
Left e -> throwIO (ErrSnapshotDeserialiseFailure e snap)
1186+
Right x -> pure x
1187+
let SnapshotMetaData label' tableType' conf snappedLevels = snapMetaData
1188+
1189+
unless (tableType == tableType') $
1190+
throwIO (ErrSnapshotWrongTableType snap tableType tableType')
1191+
1192+
unless (label == label') $
1193+
throwIO (ErrSnapshotWrongLabel snap label label')
1194+
11741195
let conf' = applyOverride override conf
11751196
am <- newArenaManager
11761197
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 = ()

0 commit comments

Comments
 (0)