{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_HADDOCK not-home #-}
module Database.LSMTree.Internal.RunAcc (
RunAcc (..)
, new
, unsafeFinalise
, addKeyOp
, addSmallKeyOp
, addLargeKeyOp
, addLargeSerialisedKeyOp
, PageAcc.entryWouldFitInPage
, RunBloomFilterAlloc (..)
, newMBloom
, numHashFunctions
, falsePositiveRate
) where
import Control.DeepSeq (NFData (..))
import Control.Exception (assert)
import Control.Monad.ST.Strict
import Data.BloomFilter (Bloom, MBloom)
import qualified Data.BloomFilter as Bloom
import qualified Data.BloomFilter.Easy as Bloom.Easy
import qualified Data.BloomFilter.Mutable as MBloom
import Data.Primitive.PrimVar (PrimVar, modifyPrimVar, newPrimVar,
readPrimVar)
import Data.Word (Word64)
import Database.LSMTree.Internal.Assertions (fromIntegralChecked)
import Database.LSMTree.Internal.BlobRef (BlobSpan (..))
import Database.LSMTree.Internal.Chunk (Chunk)
import Database.LSMTree.Internal.Entry (Entry (..), NumEntries (..))
import Database.LSMTree.Internal.Index (Index, IndexAcc, IndexType)
import qualified Database.LSMTree.Internal.Index as Index (appendMulti,
appendSingle, newWithDefaults, unsafeEnd)
import Database.LSMTree.Internal.PageAcc (PageAcc)
import qualified Database.LSMTree.Internal.PageAcc as PageAcc
import qualified Database.LSMTree.Internal.PageAcc1 as PageAcc
import Database.LSMTree.Internal.RawOverflowPage
import Database.LSMTree.Internal.RawPage (RawPage)
import qualified Database.LSMTree.Internal.RawPage as RawPage
import Database.LSMTree.Internal.Serialise (SerialisedKey,
SerialisedValue)
data RunAcc s = RunAcc {
forall s. RunAcc s -> MBloom s SerialisedKey
mbloom :: !(MBloom s SerialisedKey)
, forall s. RunAcc s -> IndexAcc s
mindex :: !(IndexAcc s)
, forall s. RunAcc s -> PageAcc s
mpageacc :: !(PageAcc s)
, forall s. RunAcc s -> PrimVar s Int
entryCount :: !(PrimVar s Int)
}
new ::
NumEntries
-> RunBloomFilterAlloc
-> IndexType
-> ST s (RunAcc s)
new :: forall s.
NumEntries -> RunBloomFilterAlloc -> IndexType -> ST s (RunAcc s)
new NumEntries
nentries RunBloomFilterAlloc
alloc IndexType
indexType = do
MBloom s SerialisedKey
mbloom <- NumEntries -> RunBloomFilterAlloc -> ST s (MBloom s SerialisedKey)
forall s a. NumEntries -> RunBloomFilterAlloc -> ST s (MBloom s a)
newMBloom NumEntries
nentries RunBloomFilterAlloc
alloc
IndexAcc s
mindex <- IndexType -> ST s (IndexAcc s)
forall s. IndexType -> ST s (IndexAcc s)
Index.newWithDefaults IndexType
indexType
PageAcc s
mpageacc <- ST s (PageAcc s)
forall s. ST s (PageAcc s)
PageAcc.newPageAcc
PrimVar s Int
entryCount <- Int -> ST s (PrimVar (PrimState (ST s)) Int)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
a -> m (PrimVar (PrimState m) a)
newPrimVar Int
0
RunAcc s -> ST s (RunAcc s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure RunAcc{MBloom s SerialisedKey
PrimVar s Int
PageAcc s
IndexAcc s
mbloom :: MBloom s SerialisedKey
mindex :: IndexAcc s
mpageacc :: PageAcc s
entryCount :: PrimVar s Int
mbloom :: MBloom s SerialisedKey
mindex :: IndexAcc s
mpageacc :: PageAcc s
entryCount :: PrimVar s Int
..}
unsafeFinalise ::
RunAcc s
-> ST s ( Maybe RawPage
, Maybe Chunk
, Bloom SerialisedKey
, Index
, NumEntries
)
unsafeFinalise :: forall s.
RunAcc s
-> ST
s
(Maybe RawPage, Maybe Chunk, Bloom SerialisedKey, Index,
NumEntries)
unsafeFinalise racc :: RunAcc s
racc@RunAcc {MBloom s SerialisedKey
PrimVar s Int
PageAcc s
IndexAcc s
mbloom :: forall s. RunAcc s -> MBloom s SerialisedKey
mindex :: forall s. RunAcc s -> IndexAcc s
mpageacc :: forall s. RunAcc s -> PageAcc s
entryCount :: forall s. RunAcc s -> PrimVar s Int
mbloom :: MBloom s SerialisedKey
mindex :: IndexAcc s
mpageacc :: PageAcc s
entryCount :: PrimVar s Int
..} = do
Maybe (RawPage, Maybe Chunk)
mpagemchunk <- RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
forall s. RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
flushPageIfNonEmpty RunAcc s
racc
(Maybe Chunk
mchunk', Index
index) <- IndexAcc s -> ST s (Maybe Chunk, Index)
forall s. IndexAcc s -> ST s (Maybe Chunk, Index)
Index.unsafeEnd IndexAcc s
mindex
Bloom SerialisedKey
bloom <- MBloom s SerialisedKey -> ST s (Bloom SerialisedKey)
forall s (h :: * -> *) a. MBloom' s h a -> ST s (Bloom' h a)
Bloom.unsafeFreeze MBloom s SerialisedKey
mbloom
Int
numEntries <- PrimVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> m a
readPrimVar PrimVar s Int
PrimVar (PrimState (ST s)) Int
entryCount
let !mpage :: Maybe RawPage
mpage = (RawPage, Maybe Chunk) -> RawPage
forall a b. (a, b) -> a
fst ((RawPage, Maybe Chunk) -> RawPage)
-> Maybe (RawPage, Maybe Chunk) -> Maybe RawPage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (RawPage, Maybe Chunk)
mpagemchunk
!mchunk :: Maybe Chunk
mchunk = Maybe (RawPage, Maybe Chunk) -> Maybe Chunk -> Maybe Chunk
selectChunk Maybe (RawPage, Maybe Chunk)
mpagemchunk Maybe Chunk
mchunk'
(Maybe RawPage, Maybe Chunk, Bloom SerialisedKey, Index,
NumEntries)
-> ST
s
(Maybe RawPage, Maybe Chunk, Bloom SerialisedKey, Index,
NumEntries)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe RawPage
mpage, Maybe Chunk
mchunk, Bloom SerialisedKey
bloom, Index
index, Int -> NumEntries
NumEntries Int
numEntries)
where
selectChunk :: Maybe (RawPage, Maybe Chunk)
-> Maybe Chunk
-> Maybe Chunk
selectChunk :: Maybe (RawPage, Maybe Chunk) -> Maybe Chunk -> Maybe Chunk
selectChunk (Just (RawPage
_page, Just Chunk
_chunk)) (Just Chunk
_chunk') =
[Char] -> Maybe Chunk
forall a. HasCallStack => [Char] -> a
error [Char]
"unsafeFinalise: impossible double final chunk"
selectChunk (Just (RawPage
_page, Just Chunk
chunk)) Maybe Chunk
_ = Chunk -> Maybe Chunk
forall a. a -> Maybe a
Just Chunk
chunk
selectChunk Maybe (RawPage, Maybe Chunk)
_ (Just Chunk
chunk) = Chunk -> Maybe Chunk
forall a. a -> Maybe a
Just Chunk
chunk
selectChunk Maybe (RawPage, Maybe Chunk)
_ Maybe Chunk
_ = Maybe Chunk
forall a. Maybe a
Nothing
addKeyOp ::
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addKeyOp :: forall s.
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addKeyOp RunAcc s
racc SerialisedKey
k Entry SerialisedValue BlobSpan
e
| SerialisedKey -> Entry SerialisedValue BlobSpan -> Bool
forall b. SerialisedKey -> Entry SerialisedValue b -> Bool
PageAcc.entryWouldFitInPage SerialisedKey
k Entry SerialisedValue BlobSpan
e = Maybe (RawPage, Maybe Chunk)
-> ([RawPage], [RawOverflowPage], [Chunk])
smallToLarge (Maybe (RawPage, Maybe Chunk)
-> ([RawPage], [RawOverflowPage], [Chunk]))
-> ST s (Maybe (RawPage, Maybe Chunk))
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s (Maybe (RawPage, Maybe Chunk))
forall s.
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s (Maybe (RawPage, Maybe Chunk))
addSmallKeyOp RunAcc s
racc SerialisedKey
k Entry SerialisedValue BlobSpan
e
| Bool
otherwise = RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall s.
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addLargeKeyOp RunAcc s
racc SerialisedKey
k Entry SerialisedValue BlobSpan
e
where
smallToLarge :: Maybe (RawPage, Maybe Chunk)
-> ([RawPage], [RawOverflowPage], [Chunk])
smallToLarge :: Maybe (RawPage, Maybe Chunk)
-> ([RawPage], [RawOverflowPage], [Chunk])
smallToLarge Maybe (RawPage, Maybe Chunk)
Nothing = ([], [], [])
smallToLarge (Just (RawPage
page, Maybe Chunk
Nothing)) = ([RawPage
page], [], [])
smallToLarge (Just (RawPage
page, Just Chunk
chunk)) = ([RawPage
page], [], [Chunk
chunk])
addSmallKeyOp ::
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s (Maybe (RawPage, Maybe Chunk))
addSmallKeyOp :: forall s.
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s (Maybe (RawPage, Maybe Chunk))
addSmallKeyOp racc :: RunAcc s
racc@RunAcc{MBloom s SerialisedKey
PrimVar s Int
PageAcc s
IndexAcc s
mbloom :: forall s. RunAcc s -> MBloom s SerialisedKey
mindex :: forall s. RunAcc s -> IndexAcc s
mpageacc :: forall s. RunAcc s -> PageAcc s
entryCount :: forall s. RunAcc s -> PrimVar s Int
mbloom :: MBloom s SerialisedKey
mindex :: IndexAcc s
mpageacc :: PageAcc s
entryCount :: PrimVar s Int
..} SerialisedKey
k Entry SerialisedValue BlobSpan
e =
Bool
-> ST s (Maybe (RawPage, Maybe Chunk))
-> ST s (Maybe (RawPage, Maybe Chunk))
forall a. HasCallStack => Bool -> a -> a
assert (SerialisedKey -> Entry SerialisedValue BlobSpan -> Bool
forall b. SerialisedKey -> Entry SerialisedValue b -> Bool
PageAcc.entryWouldFitInPage SerialisedKey
k Entry SerialisedValue BlobSpan
e) (ST s (Maybe (RawPage, Maybe Chunk))
-> ST s (Maybe (RawPage, Maybe Chunk)))
-> ST s (Maybe (RawPage, Maybe Chunk))
-> ST s (Maybe (RawPage, Maybe Chunk))
forall a b. (a -> b) -> a -> b
$ do
PrimVar (PrimState (ST s)) Int -> (Int -> Int) -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> (a -> a) -> m ()
modifyPrimVar PrimVar s Int
PrimVar (PrimState (ST s)) Int
entryCount (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
MBloom s SerialisedKey -> SerialisedKey -> ST s ()
forall (h :: * -> *) a s.
(Hashes h, Hashable a) =>
MBloom' s h a -> a -> ST s ()
MBloom.insert MBloom s SerialisedKey
mbloom SerialisedKey
k
Bool
pageBoundaryNeeded <-
Bool -> Bool
not (Bool -> Bool) -> ST s Bool -> ST s Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PageAcc s
-> SerialisedKey -> Entry SerialisedValue BlobSpan -> ST s Bool
forall s.
PageAcc s
-> SerialisedKey -> Entry SerialisedValue BlobSpan -> ST s Bool
PageAcc.pageAccAddElem PageAcc s
mpageacc SerialisedKey
k Entry SerialisedValue BlobSpan
e
if Bool
pageBoundaryNeeded
then do
Maybe (RawPage, Maybe Chunk)
mpagemchunk <- RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
forall s. RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
flushPageIfNonEmpty RunAcc s
racc
Bool
added <- PageAcc s
-> SerialisedKey -> Entry SerialisedValue BlobSpan -> ST s Bool
forall s.
PageAcc s
-> SerialisedKey -> Entry SerialisedValue BlobSpan -> ST s Bool
PageAcc.pageAccAddElem PageAcc s
mpageacc SerialisedKey
k Entry SerialisedValue BlobSpan
e
Bool
-> ST s (Maybe (RawPage, Maybe Chunk))
-> ST s (Maybe (RawPage, Maybe Chunk))
forall a. HasCallStack => Bool -> a -> a
assert Bool
added (ST s (Maybe (RawPage, Maybe Chunk))
-> ST s (Maybe (RawPage, Maybe Chunk)))
-> ST s (Maybe (RawPage, Maybe Chunk))
-> ST s (Maybe (RawPage, Maybe Chunk))
forall a b. (a -> b) -> a -> b
$ Maybe (RawPage, Maybe Chunk) -> ST s (Maybe (RawPage, Maybe Chunk))
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RawPage, Maybe Chunk)
mpagemchunk
else Maybe (RawPage, Maybe Chunk) -> ST s (Maybe (RawPage, Maybe Chunk))
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (RawPage, Maybe Chunk)
forall a. Maybe a
Nothing
addLargeKeyOp ::
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addLargeKeyOp :: forall s.
RunAcc s
-> SerialisedKey
-> Entry SerialisedValue BlobSpan
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addLargeKeyOp racc :: RunAcc s
racc@RunAcc{MBloom s SerialisedKey
PrimVar s Int
PageAcc s
IndexAcc s
mbloom :: forall s. RunAcc s -> MBloom s SerialisedKey
mindex :: forall s. RunAcc s -> IndexAcc s
mpageacc :: forall s. RunAcc s -> PageAcc s
entryCount :: forall s. RunAcc s -> PrimVar s Int
mbloom :: MBloom s SerialisedKey
mindex :: IndexAcc s
mpageacc :: PageAcc s
entryCount :: PrimVar s Int
..} SerialisedKey
k Entry SerialisedValue BlobSpan
e =
Bool
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. HasCallStack => Bool -> a -> a
assert (Bool -> Bool
not (SerialisedKey -> Entry SerialisedValue BlobSpan -> Bool
forall b. SerialisedKey -> Entry SerialisedValue b -> Bool
PageAcc.entryWouldFitInPage SerialisedKey
k Entry SerialisedValue BlobSpan
e)) (ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk]))
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a b. (a -> b) -> a -> b
$ do
PrimVar (PrimState (ST s)) Int -> (Int -> Int) -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> (a -> a) -> m ()
modifyPrimVar PrimVar s Int
PrimVar (PrimState (ST s)) Int
entryCount (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
MBloom s SerialisedKey -> SerialisedKey -> ST s ()
forall (h :: * -> *) a s.
(Hashes h, Hashable a) =>
MBloom' s h a -> a -> ST s ()
MBloom.insert MBloom s SerialisedKey
mbloom SerialisedKey
k
Maybe (RawPage, Maybe Chunk)
mpagemchunkPre <- RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
forall s. RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
flushPageIfNonEmpty RunAcc s
racc
let (RawPage
page, [RawOverflowPage]
overflowPages) = SerialisedKey
-> Entry SerialisedValue BlobSpan -> (RawPage, [RawOverflowPage])
PageAcc.singletonPage SerialisedKey
k Entry SerialisedValue BlobSpan
e
[Chunk]
chunks <- (SerialisedKey, Word32) -> IndexAcc s -> ST s [Chunk]
forall s. (SerialisedKey, Word32) -> IndexAcc s -> ST s [Chunk]
Index.appendMulti (SerialisedKey
k, Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([RawOverflowPage] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [RawOverflowPage]
overflowPages)) IndexAcc s
mindex
let (![RawPage]
pages, ![Chunk]
chunks') = Maybe (RawPage, Maybe Chunk)
-> RawPage -> [Chunk] -> ([RawPage], [Chunk])
selectPagesAndChunks Maybe (RawPage, Maybe Chunk)
mpagemchunkPre RawPage
page [Chunk]
chunks
([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ([RawPage]
pages, [RawOverflowPage]
overflowPages, [Chunk]
chunks')
addLargeSerialisedKeyOp ::
RunAcc s
-> SerialisedKey
-> RawPage
-> [RawOverflowPage]
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addLargeSerialisedKeyOp :: forall s.
RunAcc s
-> SerialisedKey
-> RawPage
-> [RawOverflowPage]
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
addLargeSerialisedKeyOp racc :: RunAcc s
racc@RunAcc{MBloom s SerialisedKey
PrimVar s Int
PageAcc s
IndexAcc s
mbloom :: forall s. RunAcc s -> MBloom s SerialisedKey
mindex :: forall s. RunAcc s -> IndexAcc s
mpageacc :: forall s. RunAcc s -> PageAcc s
entryCount :: forall s. RunAcc s -> PrimVar s Int
mbloom :: MBloom s SerialisedKey
mindex :: IndexAcc s
mpageacc :: PageAcc s
entryCount :: PrimVar s Int
..} SerialisedKey
k RawPage
page [RawOverflowPage]
overflowPages =
Bool
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. HasCallStack => Bool -> a -> a
assert (RawPage -> Word16
RawPage.rawPageNumKeys RawPage
page Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
== Word16
1) (ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk]))
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a b. (a -> b) -> a -> b
$
Bool
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. HasCallStack => Bool -> a -> a
assert (RawPage -> Int -> Word64
RawPage.rawPageHasBlobSpanAt RawPage
page Int
0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0) (ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk]))
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a b. (a -> b) -> a -> b
$
Bool
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. HasCallStack => Bool -> a -> a
assert (RawPage -> Int
RawPage.rawPageOverflowPages RawPage
page Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk]))
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a b. (a -> b) -> a -> b
$
Bool
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. HasCallStack => Bool -> a -> a
assert (RawPage -> Int
RawPage.rawPageOverflowPages RawPage
page Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [RawOverflowPage] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [RawOverflowPage]
overflowPages) (ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk]))
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a b. (a -> b) -> a -> b
$ do
PrimVar (PrimState (ST s)) Int -> (Int -> Int) -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> (a -> a) -> m ()
modifyPrimVar PrimVar s Int
PrimVar (PrimState (ST s)) Int
entryCount (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
MBloom s SerialisedKey -> SerialisedKey -> ST s ()
forall (h :: * -> *) a s.
(Hashes h, Hashable a) =>
MBloom' s h a -> a -> ST s ()
MBloom.insert MBloom s SerialisedKey
mbloom SerialisedKey
k
Maybe (RawPage, Maybe Chunk)
mpagemchunkPre <- RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
forall s. RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
flushPageIfNonEmpty RunAcc s
racc
let nOverflowPages :: Int
nOverflowPages = [RawOverflowPage] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [RawOverflowPage]
overflowPages
[Chunk]
chunks <- (SerialisedKey, Word32) -> IndexAcc s -> ST s [Chunk]
forall s. (SerialisedKey, Word32) -> IndexAcc s -> ST s [Chunk]
Index.appendMulti (SerialisedKey
k, Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nOverflowPages) IndexAcc s
mindex
let (![RawPage]
pages, ![Chunk]
chunks') = Maybe (RawPage, Maybe Chunk)
-> RawPage -> [Chunk] -> ([RawPage], [Chunk])
selectPagesAndChunks Maybe (RawPage, Maybe Chunk)
mpagemchunkPre RawPage
page [Chunk]
chunks
([RawPage], [RawOverflowPage], [Chunk])
-> ST s ([RawPage], [RawOverflowPage], [Chunk])
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ([RawPage]
pages, [RawOverflowPage]
overflowPages, [Chunk]
chunks')
flushPageIfNonEmpty :: RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
flushPageIfNonEmpty :: forall s. RunAcc s -> ST s (Maybe (RawPage, Maybe Chunk))
flushPageIfNonEmpty RunAcc{PageAcc s
mpageacc :: forall s. RunAcc s -> PageAcc s
mpageacc :: PageAcc s
mpageacc, IndexAcc s
mindex :: forall s. RunAcc s -> IndexAcc s
mindex :: IndexAcc s
mindex} = do
Int
nkeys <- PageAcc s -> ST s Int
forall s. PageAcc s -> ST s Int
PageAcc.keysCountPageAcc PageAcc s
mpageacc
if Int
nkeys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then do
SerialisedKey
minKey <- PageAcc s -> Int -> ST s SerialisedKey
forall s. PageAcc s -> Int -> ST s SerialisedKey
PageAcc.indexKeyPageAcc PageAcc s
mpageacc Int
0
SerialisedKey
maxKey <- PageAcc s -> Int -> ST s SerialisedKey
forall s. PageAcc s -> Int -> ST s SerialisedKey
PageAcc.indexKeyPageAcc PageAcc s
mpageacc (Int
nkeysInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
Maybe Chunk
mchunk <- (SerialisedKey, SerialisedKey) -> IndexAcc s -> ST s (Maybe Chunk)
forall s.
(SerialisedKey, SerialisedKey) -> IndexAcc s -> ST s (Maybe Chunk)
Index.appendSingle (SerialisedKey
minKey, SerialisedKey
maxKey) IndexAcc s
mindex
RawPage
page <- PageAcc s -> ST s RawPage
forall s. PageAcc s -> ST s RawPage
PageAcc.serialisePageAcc PageAcc s
mpageacc
PageAcc s -> ST s ()
forall s. PageAcc s -> ST s ()
PageAcc.resetPageAcc PageAcc s
mpageacc
Maybe (RawPage, Maybe Chunk) -> ST s (Maybe (RawPage, Maybe Chunk))
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ((RawPage, Maybe Chunk) -> Maybe (RawPage, Maybe Chunk)
forall a. a -> Maybe a
Just (RawPage
page, Maybe Chunk
mchunk))
else Maybe (RawPage, Maybe Chunk) -> ST s (Maybe (RawPage, Maybe Chunk))
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (RawPage, Maybe Chunk)
forall a. Maybe a
Nothing
selectPagesAndChunks :: Maybe (RawPage, Maybe Chunk)
-> RawPage
-> [Chunk]
-> ([RawPage], [Chunk])
selectPagesAndChunks :: Maybe (RawPage, Maybe Chunk)
-> RawPage -> [Chunk] -> ([RawPage], [Chunk])
selectPagesAndChunks Maybe (RawPage, Maybe Chunk)
mpagemchunkPre RawPage
page [Chunk]
chunks =
case Maybe (RawPage, Maybe Chunk)
mpagemchunkPre of
Maybe (RawPage, Maybe Chunk)
Nothing -> ( [RawPage
page], [Chunk]
chunks)
Just (RawPage
pagePre, Maybe Chunk
Nothing) -> ([RawPage
pagePre, RawPage
page], [Chunk]
chunks)
Just (RawPage
pagePre, Just Chunk
chunkPre) -> ([RawPage
pagePre, RawPage
page], Chunk
chunkPreChunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
:[Chunk]
chunks)
data RunBloomFilterAlloc =
RunAllocFixed !Word64
| RunAllocRequestFPR !Double
deriving stock (Int -> RunBloomFilterAlloc -> ShowS
[RunBloomFilterAlloc] -> ShowS
RunBloomFilterAlloc -> [Char]
(Int -> RunBloomFilterAlloc -> ShowS)
-> (RunBloomFilterAlloc -> [Char])
-> ([RunBloomFilterAlloc] -> ShowS)
-> Show RunBloomFilterAlloc
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RunBloomFilterAlloc -> ShowS
showsPrec :: Int -> RunBloomFilterAlloc -> ShowS
$cshow :: RunBloomFilterAlloc -> [Char]
show :: RunBloomFilterAlloc -> [Char]
$cshowList :: [RunBloomFilterAlloc] -> ShowS
showList :: [RunBloomFilterAlloc] -> ShowS
Show, RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool
(RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool)
-> (RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool)
-> Eq RunBloomFilterAlloc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool
== :: RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool
$c/= :: RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool
/= :: RunBloomFilterAlloc -> RunBloomFilterAlloc -> Bool
Eq)
instance NFData RunBloomFilterAlloc where
rnf :: RunBloomFilterAlloc -> ()
rnf (RunAllocFixed Word64
a) = Word64 -> ()
forall a. NFData a => a -> ()
rnf Word64
a
rnf (RunAllocRequestFPR Double
a) = Double -> ()
forall a. NFData a => a -> ()
rnf Double
a
newMBloom :: NumEntries -> RunBloomFilterAlloc -> ST s (MBloom s a)
newMBloom :: forall s a. NumEntries -> RunBloomFilterAlloc -> ST s (MBloom s a)
newMBloom (NumEntries Int
nentries) = \case
RunAllocFixed !Word64
bitsPerEntry ->
let !nbits :: Integer
nbits = Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
bitsPerEntry Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nentries
in Int -> Word64 -> ST s (MBloom s a)
forall s (h :: * -> *) a. Int -> Word64 -> ST s (MBloom' s h a)
MBloom.new
(Integer -> Int
forall a b.
(HasCallStack, Integral a, Integral b, Show a) =>
a -> b
fromIntegralChecked (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
numHashFunctions Integer
nbits (Int -> Integer
forall a b.
(HasCallStack, Integral a, Integral b, Show a) =>
a -> b
fromIntegralChecked Int
nentries))
(Integer -> Word64
forall a b.
(HasCallStack, Integral a, Integral b, Show a) =>
a -> b
fromIntegralChecked Integer
nbits)
RunAllocRequestFPR !Double
fpr ->
Double -> Int -> ST s (MBloom s a)
forall s a. Double -> Int -> ST s (MBloom s a)
Bloom.Easy.easyNew Double
fpr Int
nentries
numHashFunctions ::
Integer
-> Integer
-> Integer
numHashFunctions :: Integer -> Integer -> Integer
numHashFunctions Integer
nbits Integer
nentries = forall a b. (RealFrac a, Integral b) => a -> b
truncate @Double (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$
(Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
nbits Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
nentries) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
log Double
2
falsePositiveRate ::
Floating a
=> a
-> a
-> a
falsePositiveRate :: forall a. Floating a => a -> a -> a
falsePositiveRate a
entries a
bits = a -> a
forall a. Floating a => a -> a
exp ((-(a
bits a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
entries)) a -> a -> a
forall a. Num a => a -> a -> a
* a -> a
forall a. Num a => a -> a
sq (a -> a
forall a. Floating a => a -> a
log a
2))
sq :: Num a => a -> a
sq :: forall a. Num a => a -> a
sq a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
x