Skip to content

Commit 65c3f04

Browse files
committed
Change RawBlobRef to contain a BlobFile
Originally it contained the file handle and the refcounter of either the Run or write buffer that the blob ref came from (pointed to). In a previous patch we changed the Run and WriteBufferBlobs to themselves contain an independently ref-counted BlobFile, and so at the same time the blob ref refcount refers to the blob file refcount not the refcount of the parent object. In this patch we now change RawBlobRef to directly hold a BlobFile. This makes the representation logically more uniform between the run and write buffer cases: since we now just point to the BlobFile being held by each blob source. This refactoring will make things much clearer once we switch the representation of ref-counted objects. Since we'll maintain a reference to a BlobFile rather than a lower-level combo of a file handle and reference count.
1 parent d49ccbc commit 65c3f04

File tree

3 files changed

+21
-37
lines changed

3 files changed

+21
-37
lines changed

src/Database/LSMTree/Internal/BlobRef.hs

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,12 @@ import Control.Monad (when)
2424
import Control.Monad.Class.MonadThrow (Exception, MonadMask,
2525
MonadThrow (..), bracket, throwIO)
2626
import Control.Monad.Primitive
27-
import Control.RefCount (RefCounter)
2827
import qualified Control.RefCount as RC
2928
import Data.Coerce (coerce)
30-
import qualified Data.Primitive.ByteArray as P (MutableByteArray,
31-
newPinnedByteArray, unsafeFreezeByteArray)
29+
import qualified Data.Primitive.ByteArray as P (MutableByteArray)
3230
import qualified Data.Vector as V
33-
import Database.LSMTree.Internal.BlobFile (BlobSpan (..))
34-
import qualified Database.LSMTree.Internal.RawBytes as RB
31+
import Database.LSMTree.Internal.BlobFile (BlobFile (..), BlobSpan (..))
32+
import qualified Database.LSMTree.Internal.BlobFile as BlobFile
3533
import Database.LSMTree.Internal.Serialise (SerialisedBlob (..))
3634
import qualified System.FS.API as FS
3735
import System.FS.API (HasFS)
@@ -48,17 +46,16 @@ import qualified System.FS.BlockIO.API as FS
4846
-- Thus these cannot be handed out via the API. Use 'WeakBlobRef' for that.
4947
--
5048
data RawBlobRef m h = RawBlobRef {
51-
blobRefFile :: !(FS.Handle h)
52-
, blobRefCount :: {-# UNPACK #-} !(RefCounter m)
53-
, blobRefSpan :: {-# UNPACK #-} !BlobSpan
49+
rawBlobRefFile :: {-# NOUNPACK #-} !(BlobFile m h)
50+
, rawBlobRefSpan :: {-# UNPACK #-} !BlobSpan
5451
}
5552
deriving stock (Show)
5653

5754
instance NFData h => NFData (RawBlobRef m h) where
58-
rnf (RawBlobRef a b c) = rnf a `seq` rnf b `seq` rnf c
55+
rnf (RawBlobRef a b) = rnf a `seq` rnf b
5956

6057
blobRefSpanSize :: RawBlobRef m h -> Int
61-
blobRefSpanSize = fromIntegral . blobSpanSize . blobRefSpan
58+
blobRefSpanSize = fromIntegral . blobSpanSize . rawBlobRefSpan
6259

6360
-- | A \"weak\" reference to a blob within a blob file. These are the ones we
6461
-- can return in the public API and can outlive their parent table.
@@ -117,7 +114,7 @@ deRefWeakBlobRef ::
117114
=> WeakBlobRef m h
118115
-> m (RawBlobRef m h)
119116
deRefWeakBlobRef (WeakBlobRef ref) = do
120-
ok <- RC.upgradeWeakReference (blobRefCount ref)
117+
ok <- RC.upgradeWeakReference (blobFileRefCounter (rawBlobRefFile ref))
121118
when (not ok) $ throwIO (WeakBlobRefInvalid 0)
122119
pure ref
123120

@@ -133,7 +130,7 @@ deRefWeakBlobRefs wrefs = do
133130
let refs :: V.Vector (RawBlobRef m h)
134131
refs = coerce wrefs -- safely coerce away the newtype wrappers
135132
V.iforM_ wrefs $ \i (WeakBlobRef ref) -> do
136-
ok <- RC.upgradeWeakReference (blobRefCount ref)
133+
ok <- RC.upgradeWeakReference (blobFileRefCounter (rawBlobRefFile ref))
137134
when (not ok) $ do
138135
-- drop refs on the previous ones taken successfully so far
139136
V.mapM_ removeReference (V.take i refs)
@@ -142,7 +139,7 @@ deRefWeakBlobRefs wrefs = do
142139

143140
{-# SPECIALISE removeReference :: RawBlobRef IO h -> IO () #-}
144141
removeReference :: (MonadMask m, PrimMonad m) => RawBlobRef m h -> m ()
145-
removeReference = RC.removeReference . blobRefCount
142+
removeReference = BlobFile.removeReference . rawBlobRefFile
146143

147144
{-# SPECIALISE removeReferences :: V.Vector (RawBlobRef IO h) -> IO () #-}
148145
removeReferences :: (MonadMask m, PrimMonad m) => V.Vector (RawBlobRef m h) -> m ()
@@ -157,31 +154,20 @@ readBlob ::
157154
=> HasFS m h
158155
-> RawBlobRef m h
159156
-> m SerialisedBlob
160-
readBlob fs RawBlobRef {
161-
blobRefFile,
162-
blobRefSpan = BlobSpan {blobSpanOffset, blobSpanSize}
163-
} = do
164-
let off = FS.AbsOffset blobSpanOffset
165-
len :: Int
166-
len = fromIntegral blobSpanSize
167-
mba <- P.newPinnedByteArray len
168-
_ <- FS.hGetBufExactlyAt fs blobRefFile mba 0
169-
(fromIntegral len :: FS.ByteCount) off
170-
ba <- P.unsafeFreezeByteArray mba
171-
let !rb = RB.fromByteArray 0 len ba
172-
return (SerialisedBlob rb)
157+
readBlob fs RawBlobRef {rawBlobRefFile, rawBlobRefSpan} =
158+
BlobFile.readBlobFile fs rawBlobRefFile rawBlobRefSpan
173159

174160
readBlobIOOp ::
175161
P.MutableByteArray s -> Int
176162
-> RawBlobRef m h
177163
-> FS.IOOp s h
178164
readBlobIOOp buf bufoff
179165
RawBlobRef {
180-
blobRefFile,
181-
blobRefSpan = BlobSpan {blobSpanOffset, blobSpanSize}
166+
rawBlobRefFile = BlobFile {blobFileHandle},
167+
rawBlobRefSpan = BlobSpan {blobSpanOffset, blobSpanSize}
182168
} =
183169
FS.IOOpRead
184-
blobRefFile
170+
blobFileHandle
185171
(fromIntegral blobSpanOffset :: FS.FileOffset)
186172
buf (FS.BufferOffset bufoff)
187173
(fromIntegral blobSpanSize :: FS.ByteCount)

src/Database/LSMTree/Internal/Run.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,10 @@ removeReferenceN r = RC.removeReferenceN (runRefCounter r)
145145

146146
-- | Helper function to make a 'BlobRef' that points into a 'Run'.
147147
mkBlobRefForRun :: Run m h -> BlobSpan -> RawBlobRef m h
148-
mkBlobRefForRun Run{runBlobFile} blobRefSpan =
148+
mkBlobRefForRun Run{runBlobFile} blobspan =
149149
RawBlobRef {
150-
blobRefFile = blobFileHandle runBlobFile,
151-
blobRefCount = blobFileRefCounter runBlobFile,
152-
blobRefSpan
150+
rawBlobRefFile = runBlobFile,
151+
rawBlobRefSpan = blobspan
153152
}
154153

155154
{-# SPECIALISE close ::

src/Database/LSMTree/Internal/WriteBufferBlobs.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,10 @@ readBlob fs WriteBufferBlobs {blobFile} blobspan =
182182
mkBlobRef :: WriteBufferBlobs m h
183183
-> BlobSpan
184184
-> RawBlobRef m h
185-
mkBlobRef WriteBufferBlobs {blobFile} blobRefSpan =
185+
mkBlobRef WriteBufferBlobs {blobFile} blobspan =
186186
RawBlobRef {
187-
blobRefFile = blobFileHandle blobFile,
188-
blobRefCount = blobFileRefCounter blobFile,
189-
blobRefSpan
187+
rawBlobRefFile = blobFile,
188+
rawBlobRefSpan = blobspan
190189
}
191190

192191

0 commit comments

Comments
 (0)