Skip to content

Commit ffd6e60

Browse files
committed
Resolve PR comments
1 parent be93aed commit ffd6e60

File tree

6 files changed

+169
-126
lines changed

6 files changed

+169
-126
lines changed

src/Database/LSMTree/Internal.hs

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,10 @@ openSession tr hfs hbio dir = do
431431
-- is automatically released by bracketOnError.
432432
checkTopLevelDirLayout
433433

434-
FS.removeDirectoryRecursive hfs activeDirPath -- TODO: exceptions safety
435-
FS.createDirectory hfs activeDirPath
434+
-- Clear the active directory by removing the directory and recreating
435+
-- it again.
436+
FS.removeDirectoryRecursive hfs activeDirPath
437+
`finally` FS.createDirectoryIfMissing hfs False activeDirPath
436438

437439
checkActiveDirLayout
438440
checkSnapshotsDirLayout
@@ -1064,55 +1066,58 @@ createSnapshot ::
10641066
createSnapshot resolve snap label tableType t = do
10651067
traceWith (tableTracer t) $ TraceSnapshot snap
10661068
let conf = tableConfig t
1067-
withOpenTable t $ \thEnv -> do
1068-
let hfs = tableHasFS thEnv
1069-
1070-
-- Guard that the snapshot does not exist already
1071-
let snapDir = Paths.namedSnapshotDir (tableSessionRoot thEnv) snap
1072-
doesSnapshotExist <-
1073-
FS.doesDirectoryExist (tableHasFS thEnv) (Paths.getNamedSnapshotDir snapDir)
1074-
if doesSnapshotExist then
1075-
throwIO (ErrSnapshotExists snap)
1076-
else
1077-
-- we assume the snapshots directory already exists, so we just have to
1078-
-- create the directory for this specific snapshot.
1079-
FS.createDirectory hfs (Paths.getNamedSnapshotDir snapDir)
1080-
1081-
-- For the temporary implementation it is okay to just flush the buffer
1082-
-- before taking the snapshot.
1083-
content <- modifyWithTempRegistry
1084-
(RW.unsafeAcquireWriteAccess (tableContent thEnv))
1085-
(atomically . RW.unsafeReleaseWriteAccess (tableContent thEnv))
1086-
$ \reg content -> do
1087-
-- TODO: When we flush the buffer here, it might be underfull, which
1088-
-- could mess up the scheduling. The conservative approach is to supply
1089-
-- credits as if the buffer was full, and then flush the (possibly)
1090-
-- underfull buffer. However, note that this bit of code
1091-
-- here is probably going to change anyway because of #392
1092-
supplyCredits conf (Credit $ unNumEntries $ case confWriteBufferAlloc conf of AllocNumEntries x -> x) (tableLevels content)
1093-
content' <- flushWriteBuffer
1094-
(TraceMerge `contramap` tableTracer t)
1095-
conf
1096-
resolve
1097-
hfs
1098-
(tableHasBlockIO thEnv)
1099-
(tableSessionRoot thEnv)
1100-
(tableSessionUniqCounter thEnv)
1101-
reg
1102-
content
1103-
pure (content', content')
1104-
-- At this point, we've flushed the write buffer but we haven't created the
1105-
-- snapshot file yet. If an asynchronous exception happens beyond this
1106-
-- point, we'll take that loss, as the inner state of the table is still
1107-
-- consistent.
1108-
1109-
snappedLevels <- snapLevels (tableLevels content)
1110-
snappedLevels' <- snapshotRuns snapDir snappedLevels
1111-
1112-
let snapMetaData = SnapshotMetaData label tableType (tableConfig t) snappedLevels'
1113-
SnapshotMetaDataFile contentPath = Paths.snapshotMetaDataFile snapDir
1114-
SnapshotMetaDataChecksumFile checksumPath = Paths.snapshotMetaDataChecksumFile snapDir
1115-
writeFileSnapshotMetaData hfs contentPath checksumPath snapMetaData
1069+
withOpenTable t $ \thEnv ->
1070+
withTempRegistry $ \reg -> do -- TODO: use the temp registry for all side effects
1071+
let hfs = tableHasFS thEnv
1072+
1073+
-- Guard that the snapshot does not exist already
1074+
let snapDir = Paths.namedSnapshotDir (tableSessionRoot thEnv) snap
1075+
doesSnapshotExist <-
1076+
FS.doesDirectoryExist (tableHasFS thEnv) (Paths.getNamedSnapshotDir snapDir)
1077+
if doesSnapshotExist then
1078+
throwIO (ErrSnapshotExists snap)
1079+
else
1080+
-- we assume the snapshots directory already exists, so we just have to
1081+
-- create the directory for this specific snapshot.
1082+
FS.createDirectory hfs (Paths.getNamedSnapshotDir snapDir)
1083+
1084+
-- For the temporary implementation it is okay to just flush the buffer
1085+
-- before taking the snapshot.
1086+
content <- modifyWithTempRegistry
1087+
(RW.unsafeAcquireWriteAccess (tableContent thEnv))
1088+
(atomically . RW.unsafeReleaseWriteAccess (tableContent thEnv))
1089+
$ \innerReg content -> do
1090+
-- TODO: When we flush the buffer here, it might be underfull, which
1091+
-- could mess up the scheduling. The conservative approach is to supply
1092+
-- credits as if the buffer was full, and then flush the (possibly)
1093+
-- underfull buffer. However, note that this bit of code
1094+
-- here is probably going to change anyway because of #392
1095+
supplyCredits conf (Credit $ unNumEntries $ case confWriteBufferAlloc conf of AllocNumEntries x -> x) (tableLevels content)
1096+
content' <- flushWriteBuffer
1097+
(TraceMerge `contramap` tableTracer t)
1098+
conf
1099+
resolve
1100+
hfs
1101+
(tableHasBlockIO thEnv)
1102+
(tableSessionRoot thEnv)
1103+
(tableSessionUniqCounter thEnv)
1104+
innerReg
1105+
content
1106+
pure (content', content')
1107+
-- At this point, we've flushed the write buffer but we haven't created the
1108+
-- snapshot file yet. If an asynchronous exception happens beyond this
1109+
-- point, we'll take that loss, as the inner state of the table is still
1110+
-- consistent.
1111+
1112+
-- Convert to snapshot format
1113+
snapLevels <- toSnapLevels (tableLevels content)
1114+
-- Hard link runs into the named snapshot directory
1115+
snapLevels' <- snapshotRuns reg snapDir snapLevels
1116+
1117+
let snapMetaData = SnapshotMetaData label tableType (tableConfig t) snapLevels'
1118+
SnapshotMetaDataFile contentPath = Paths.snapshotMetaDataFile snapDir
1119+
SnapshotMetaDataChecksumFile checksumPath = Paths.snapshotMetaDataChecksumFile snapDir
1120+
writeFileSnapshotMetaData hfs contentPath checksumPath snapMetaData
11161121

11171122
{-# SPECIALISE openSnapshot ::
11181123
Session IO h
@@ -1150,7 +1155,7 @@ openSnapshot sesh label tableType override snap resolve = do
11501155
Left e -> throwIO (ErrSnapshotDeserialiseFailure e snap)
11511156
Right x -> pure x
11521157

1153-
let SnapshotMetaData label' tableType' conf snappedLevels = snapMetaData
1158+
let SnapshotMetaData label' tableType' conf snapLevels = snapMetaData
11541159

11551160
unless (tableType == tableType') $
11561161
throwIO (ErrSnapshotWrongTableType snap tableType tableType')
@@ -1168,8 +1173,11 @@ openSnapshot sesh label tableType override snap resolve = do
11681173
WBB.removeReference
11691174

11701175
let actDir = Paths.activeDir (sessionRoot seshEnv)
1171-
snappedLevels' <- openRuns hfs hbio conf (sessionUniqCounter seshEnv) snapDir actDir snappedLevels
1172-
tableLevels <- openLevels reg hfs hbio conf (sessionUniqCounter seshEnv) resolve actDir snappedLevels'
1176+
1177+
-- Hard link runs into the active directory,
1178+
snapLevels' <- openRuns reg hfs hbio conf (sessionUniqCounter seshEnv) snapDir actDir snapLevels
1179+
-- Convert from the snapshot format, restoring merge progress in the process
1180+
tableLevels <- fromSnapLevels reg hfs hbio conf (sessionUniqCounter seshEnv) resolve actDir snapLevels'
11731181

11741182
tableCache <- mkLevelsCache reg tableLevels
11751183
newWith reg sesh seshEnv conf' am $! TableContent {

src/Database/LSMTree/Internal/CRC32C.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ module Database.LSMTree.Internal.CRC32C (
4141
readChecksumsFile,
4242
writeChecksumsFile,
4343
writeChecksumsFile',
44-
45-
hexdigitsToInt
4644
) where
4745

4846
import Control.Monad

src/Database/LSMTree/Internal/Run.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,12 @@ mkWeakBlobRef Run{runBlobFile} blobspan =
138138
-> IO () #-}
139139
-- | Close the files used in the run and remove them from disk. After calling
140140
-- this operation, the run must not be used anymore.
141+
--
142+
-- TODO: exception safety
141143
close :: (MonadSTM m, MonadMask m, PrimMonad m) => Run m h -> m ()
142144
close Run {..} = do
143145
FS.hClose runHasFS runKOpsFile
144146
BlobFile.removeReference runBlobFile
145-
146147
FS.removeFile runHasFS (runKOpsPath runRunFsPaths)
147148
FS.removeFile runHasFS (runFilterPath runRunFsPaths)
148149
FS.removeFile runHasFS (runIndexPath runRunFsPaths)

0 commit comments

Comments
 (0)