Skip to content

Commit 5b8cd3c

Browse files
committed
Split openSession into newSession and restoreSession
Only the former requires a salt, and the latter does not require it. We still keep a version of `openSession` that defers to `newSession` or `restoreSession` based on the session directory contents, because we expect it to be useful for users. In `newSession`, the input salt is written to a new metadata file in the session directory. In `restoreSession`, we read this metadata file back into memory to extract the salt.
1 parent a4a9c0b commit 5b8cd3c

File tree

12 files changed

+409
-187
lines changed

12 files changed

+409
-187
lines changed

bench-unions/Bench/Unions.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ doSetup gopts = do
292292
createDirectoryIfMissing True $ rootDir gopts
293293

294294
-- Populate the specified number of tables
295-
LSM.withSession (rootDir gopts) $ \session -> do
295+
LSM.withOpenSession (rootDir gopts) $ \session -> do
296296
-- Create a "baseline" table
297297
--
298298
-- We create a single table that *already has* all the same key value pairs
@@ -337,7 +337,7 @@ tableRange gopts =
337337
-- | Count duplicate keys in all tables that will be unioned together
338338
doCollisionAnalysis :: GlobalOpts -> IO ()
339339
doCollisionAnalysis gopts = do
340-
LSM.withSession (rootDir gopts) $ \session -> do
340+
LSM.withOpenSession (rootDir gopts) $ \session -> do
341341
seenRef <- newIORef Set.empty
342342
dupRef <- newIORef Set.empty
343343

@@ -381,7 +381,7 @@ doRun gopts opts = do
381381
withFile dataPath WriteMode $ \h -> do
382382
hPutStrLn h "# iteration \t baseline (ops/sec) \t union (ops/sec) \t union debt"
383383

384-
LSM.withSession (rootDir gopts) $ \session -> do
384+
LSM.withOpenSession (rootDir gopts) $ \session -> do
385385
-- Load the baseline table
386386
LSM.withTableFromSnapshot session baselineTableName label
387387
$ \baselineTable -> do

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ doSetup' gopts opts = do
416416

417417
let name = LSM.toSnapshotName "bench"
418418

419-
LSM.withSession (mkTracer gopts) hasFS hasBlockIO benchSalt (FS.mkFsPath []) $ \session -> do
419+
LSM.withOpenSession (mkTracer gopts) hasFS hasBlockIO benchSalt (FS.mkFsPath []) $ \session -> do
420420
tbl <- LSM.newTableWith @IO @K @V @B (mkTableConfigSetup gopts opts benchTableConfig) session
421421

422422
forM_ (groupsOfN 256 [ 0 .. initialSize gopts ]) $ \batch -> do
@@ -578,7 +578,7 @@ doRun gopts opts = do
578578

579579
let name = LSM.toSnapshotName "bench"
580580

581-
LSM.withSession (mkTracer gopts) hasFS hasBlockIO benchSalt (FS.mkFsPath []) $ \session ->
581+
LSM.withOpenSession (mkTracer gopts) hasFS hasBlockIO benchSalt (FS.mkFsPath []) $ \session ->
582582
withLatencyHandle $ \h -> do
583583
-- open snapshot
584584
-- In checking mode we start with an empty table, since our pure

lsm-tree.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ library
594594
, lsm-tree:kmerge
595595
, primitive ^>=0.9
596596
, random ^>=1.0 || ^>=1.1 || ^>=1.2 || ^>=1.3
597+
, serialise ^>=0.2
597598
, text ^>=2.1.1
598599
, utf8-string ^>=1.0
599600
, vector ^>=0.13

src/Database/LSMTree.hs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ module Database.LSMTree (
1919

2020
-- * Sessions
2121
Session,
22-
withSession,
23-
withSessionIO,
22+
withOpenSession,
23+
withOpenSessionIO,
2424
openSession,
2525
openSessionIO,
2626
closeSession,
@@ -200,8 +200,8 @@ import Control.DeepSeq (NFData (..))
200200
import Control.Exception.Base (assert)
201201
import Control.Monad.Class.MonadAsync (MonadAsync)
202202
import Control.Monad.Class.MonadST (MonadST)
203-
import Control.Monad.Class.MonadThrow (MonadCatch (..), MonadMask,
204-
MonadThrow (..))
203+
import Control.Monad.Class.MonadThrow (MonadCatch (..), MonadEvaluate,
204+
MonadMask, MonadThrow (..))
205205
import Control.Monad.Primitive (PrimMonad)
206206
import Control.Tracer (Tracer)
207207
import Data.Bifunctor (Bifunctor (..))
@@ -290,6 +290,7 @@ type IOLike m =
290290
, MonadMask m
291291
, PrimMonad m
292292
, MonadST m
293+
, MonadEvaluate m
293294
)
294295

295296
--------------------------------------------------------------------------------
@@ -384,7 +385,7 @@ runExample action = do
384385
let createSessionDir = Dir.createDirectoryIfMissing True sessionDir
385386
let removeSessionDir = Dir.removeDirectoryRecursive sessionDir
386387
bracket_ createSessionDir removeSessionDir $ do
387-
LSMT.withSessionIO mempty sessionDir $ \session -> do
388+
LSMT.withOpenSessionIO mempty sessionDir $ \session -> do
388389
LSMT.withTable session $ \table ->
389390
action session table
390391
:}
@@ -399,8 +400,8 @@ runExample action = do
399400
{- |
400401
Run an action with access to a session opened from a session directory.
401402
402-
If the session directory is empty, a new session is created.
403-
Otherwise, the session directory is opened as an existing session.
403+
If the session directory is empty, a new session is created using the given salt.
404+
Otherwise, the session directory is restored as an existing session ignoring the given salt.
404405
405406
If there are no open tables or cursors when the session terminates, then the disk I\/O complexity of this operation is \(O(1)\).
406407
Otherwise, 'closeTable' is called for each open table and 'closeCursor' is called for each open cursor.
@@ -426,7 +427,7 @@ Throws the following exceptions:
426427
If the session directory is malformed.
427428
-}
428429
{-# SPECIALISE
429-
withSession ::
430+
withOpenSession ::
430431
Tracer IO LSMTreeTrace ->
431432
HasFS IO HandleIO ->
432433
HasBlockIO IO HandleIO ->
@@ -435,7 +436,7 @@ Throws the following exceptions:
435436
(Session IO -> IO a) ->
436437
IO a
437438
#-}
438-
withSession ::
439+
withOpenSession ::
439440
forall m h a.
440441
(IOLike m, Typeable h) =>
441442
Tracer m LSMTreeTrace ->
@@ -447,28 +448,28 @@ withSession ::
447448
FsPath ->
448449
(Session m -> m a) ->
449450
m a
450-
withSession tracer hasFS hasBlockIO sessionSalt sessionDir action = do
451-
Internal.withSession tracer hasFS hasBlockIO sessionSalt sessionDir (action . Session)
451+
withOpenSession tracer hasFS hasBlockIO sessionSalt sessionDir action = do
452+
Internal.withOpenSession tracer hasFS hasBlockIO sessionSalt sessionDir (action . Session)
452453

453-
-- | Variant of 'withSession' that is specialised to 'IO' using the real filesystem.
454-
withSessionIO ::
454+
-- | Variant of 'withOpenSession' that is specialised to 'IO' using the real filesystem.
455+
withOpenSessionIO ::
455456
Tracer IO LSMTreeTrace ->
456457
FilePath ->
457458
(Session IO -> IO a) ->
458459
IO a
459-
withSessionIO tracer sessionDir action = do
460+
withOpenSessionIO tracer sessionDir action = do
460461
let mountPoint = MountPoint sessionDir
461462
let sessionDirFsPath = mkFsPath []
462463
let hasFS = ioHasFS mountPoint
463464
sessionSalt <- randomIO
464465
withIOHasBlockIO hasFS defaultIOCtxParams $ \hasBlockIO ->
465-
withSession tracer hasFS hasBlockIO sessionSalt sessionDirFsPath action
466+
withOpenSession tracer hasFS hasBlockIO sessionSalt sessionDirFsPath action
466467

467468
{- |
468469
Open a session from a session directory.
469470
470-
If the session directory is empty, a new session is created.
471-
Otherwise, the session directory is opened as an existing session.
471+
If the session directory is empty, a new session is created using the given salt.
472+
Otherwise, the session directory is restored as an existing session ignoring the given salt.
472473
473474
The worst-case disk I\/O complexity of this operation is \(O(1)\).
474475

src/Database/LSMTree/Internal/Paths.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
module Database.LSMTree.Internal.Paths (
55
SessionRoot (..)
66
, lockFile
7+
, lockFileName
8+
, metadataFile
79
, ActiveDir (..)
810
, activeDir
911
, runPath
@@ -75,7 +77,13 @@ newtype SessionRoot = SessionRoot { getSessionRoot :: FsPath }
7577
deriving stock Eq
7678

7779
lockFile :: SessionRoot -> FsPath
78-
lockFile (SessionRoot dir) = dir </> mkFsPath ["lock"]
80+
lockFile (SessionRoot dir) = dir </> mkFsPath [lockFileName]
81+
82+
lockFileName :: String
83+
lockFileName = "lock"
84+
85+
metadataFile :: SessionRoot -> FsPath
86+
metadataFile (SessionRoot dir) = dir </> mkFsPath ["metadata"]
7987

8088
newtype ActiveDir = ActiveDir { getActiveDir :: FsPath }
8189

0 commit comments

Comments
 (0)