Skip to content

Commit 441f194

Browse files
authored
Merge pull request #659 from IntersectMBO/jeltsch/unsliced-keys-in-ordinary-indexes
Make ordinary indexes store their keys unsliced
2 parents 1a19e33 + 84f5ca5 commit 441f194

File tree

3 files changed

+169
-133
lines changed

3 files changed

+169
-133
lines changed

src/Database/LSMTree/Internal/Index/Ordinary.hs

+26-23
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
module Database.LSMTree.Internal.Index.Ordinary
1010
(
1111
IndexOrdinary (IndexOrdinary),
12-
toLastKeys,
12+
toUnslicedLastKeys,
1313
search,
1414
sizeInPages,
1515
headerLBS,
@@ -41,6 +41,7 @@ import Database.LSMTree.Internal.Page (NumPages (NumPages),
4141
PageNo (PageNo), PageSpan (PageSpan))
4242
import Database.LSMTree.Internal.Serialise
4343
(SerialisedKey (SerialisedKey'))
44+
import Database.LSMTree.Internal.Unsliced (Unsliced, makeUnslicedKey)
4445
import Database.LSMTree.Internal.Vector (binarySearchL, mkPrimVector)
4546

4647
{-|
@@ -66,22 +67,22 @@ supportedTypeAndVersion = 0x0101
6667
ascending order and must comprise at least one page for 'search' to be able
6768
to return a valid page span.
6869
-}
69-
newtype IndexOrdinary = IndexOrdinary (Vector SerialisedKey)
70+
newtype IndexOrdinary = IndexOrdinary (Vector (Unsliced SerialisedKey))
7071
deriving stock (Eq, Show)
7172

7273
instance NFData IndexOrdinary where
7374

74-
rnf (IndexOrdinary lastKeys) = rnf lastKeys
75+
rnf (IndexOrdinary unslicedLastKeys) = rnf unslicedLastKeys
7576

76-
toLastKeys :: IndexOrdinary -> Vector SerialisedKey
77-
toLastKeys (IndexOrdinary lastKeys) = lastKeys
77+
toUnslicedLastKeys :: IndexOrdinary -> Vector (Unsliced SerialisedKey)
78+
toUnslicedLastKeys (IndexOrdinary unslicedLastKeys) = unslicedLastKeys
7879

7980
{-|
8081
For a specification of this operation, see the documentation of [its
8182
type-agnostic version]('Database.LSMTree.Internal.Index.search').
8283
-}
8384
search :: SerialisedKey -> IndexOrdinary -> PageSpan
84-
search key (IndexOrdinary lastKeys)
85+
search key (IndexOrdinary unslicedLastKeys)
8586
-- TODO: ideally, we could assert that an index is never empty, but
8687
-- unfortunately we can not currently do this. Runs (and thefeore indexes)
8788
-- /can/ be empty if they were created by a last-level merge where all input
@@ -94,35 +95,35 @@ search key (IndexOrdinary lastKeys)
9495
| otherwise = assert (pageCount > 0) result where
9596

9697
protoStart :: Int
97-
!protoStart = binarySearchL lastKeys key
98+
!protoStart = binarySearchL unslicedLastKeys (makeUnslicedKey key)
9899

99100
pageCount :: Int
100-
!pageCount = length lastKeys
101+
!pageCount = length unslicedLastKeys
101102

102103
result :: PageSpan
103104
result | protoStart < pageCount
104105
= let
105106

106-
resultKey :: SerialisedKey
107-
!resultKey = lastKeys ! protoStart
107+
unslicedResultKey :: Unsliced SerialisedKey
108+
!unslicedResultKey = unslicedLastKeys ! protoStart
108109

109110
end :: Int
110111
!end = maybe (pred pageCount) (+ protoStart) $
111-
findIndex (/= resultKey) $
112-
drop (succ protoStart) lastKeys
112+
findIndex (/= unslicedResultKey) $
113+
drop (succ protoStart) unslicedLastKeys
113114

114115
in PageSpan (PageNo $ protoStart)
115116
(PageNo $ end)
116117
| otherwise
117118
= let
118119

119-
resultKey :: SerialisedKey
120-
!resultKey = last lastKeys
120+
unslicedResultKey :: Unsliced SerialisedKey
121+
!unslicedResultKey = last unslicedLastKeys
121122

122123
start :: Int
123124
!start = maybe 0 succ $
124-
findIndexR (/= resultKey) $
125-
lastKeys
125+
findIndexR (/= unslicedResultKey) $
126+
unslicedLastKeys
126127

127128
in PageSpan (PageNo $ start)
128129
(PageNo $ pred pageCount)
@@ -132,7 +133,8 @@ search key (IndexOrdinary lastKeys)
132133
type-agnostic version]('Database.LSMTree.Internal.Index.sizeInPages').
133134
-}
134135
sizeInPages :: IndexOrdinary -> NumPages
135-
sizeInPages (IndexOrdinary lastKeys) = NumPages $ fromIntegral (length lastKeys)
136+
sizeInPages (IndexOrdinary unslicedLastKeys)
137+
= NumPages $ fromIntegral (length unslicedLastKeys)
136138

137139
{-|
138140
For a specification of this operation, see the documentation of [its
@@ -203,10 +205,11 @@ fromSBS shortByteString@(SBS unliftedByteArray)
203205
Primitive.Vector _ _ entryCountRep = Primitive.force entryCountBytes
204206

205207
index :: Either String IndexOrdinary
206-
index = IndexOrdinary <$> fromList <$> lastKeys lastKeysBytes
208+
index = IndexOrdinary <$> fromList <$> unslicedLastKeys lastKeysBytes
207209

208-
lastKeys :: Primitive.Vector Word8 -> Either String [SerialisedKey]
209-
lastKeys bytes
210+
unslicedLastKeys :: Primitive.Vector Word8
211+
-> Either String [Unsliced SerialisedKey]
212+
unslicedLastKeys bytes
210213
| Primitive.null bytes
211214
= Right []
212215
| otherwise
@@ -234,8 +237,8 @@ fromSBS shortByteString@(SBS unliftedByteArray)
234237
(firstBytes, othersBytes)
235238
= Primitive.splitAt firstSize postFirstSizeBytes
236239

237-
first :: SerialisedKey
238-
!first = SerialisedKey' (Primitive.force firstBytes)
240+
first :: Unsliced SerialisedKey
241+
!first = makeUnslicedKey (SerialisedKey' firstBytes)
239242

240-
others <- lastKeys othersBytes
243+
others <- unslicedLastKeys othersBytes
241244
return (first : others)

src/Database/LSMTree/Internal/Index/OrdinaryAcc.hs

+21-16
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,26 @@ import Database.LSMTree.Internal.Index.Ordinary
3030
(IndexOrdinary (IndexOrdinary))
3131
import Database.LSMTree.Internal.Serialise
3232
(SerialisedKey (SerialisedKey'))
33+
import Database.LSMTree.Internal.Unsliced (Unsliced, makeUnslicedKey)
3334
import Database.LSMTree.Internal.Vector (byteVectorFromPrim)
3435
import Database.LSMTree.Internal.Vector.Growing (GrowingVector)
3536
import qualified Database.LSMTree.Internal.Vector.Growing as Growing (append,
3637
freeze, new)
3738
#ifdef NO_IGNORE_ASSERTS
39+
import Database.LSMTree.Internal.Unsliced (fromUnslicedKey)
3840
import qualified Database.LSMTree.Internal.Vector.Growing as Growing
3941
(readMaybeLast)
4042
#endif
4143

4244
{-|
4345
A general-purpose fence pointer index under incremental construction.
4446
45-
A value @IndexOrdinaryAcc lastKeys baler@ denotes a partially constructed
46-
index that assigns keys to pages according to @lastKeys@ and uses @baler@
47-
for incremental output of the serialised key list.
47+
A value @IndexOrdinaryAcc unslicedLastKeys baler@ denotes a partially
48+
constructed index that assigns keys to pages according to @unslicedLastKeys@
49+
and uses @baler@ for incremental output of the serialised key list.
4850
-}
4951
data IndexOrdinaryAcc s = IndexOrdinaryAcc
50-
!(GrowingVector s SerialisedKey)
52+
!(GrowingVector s (Unsliced SerialisedKey))
5153
!(Baler s)
5254

5355
-- | Creates a new, initially empty, index.
@@ -65,7 +67,7 @@ new initialKeyBufferSize minChunkSize = IndexOrdinaryAcc <$>
6567
newWithDefaults :: ST s (IndexOrdinaryAcc s)
6668
newWithDefaults = new 1024 4096
6769

68-
-- Yields the serialisation of an element of a key list.
70+
-- | Yields the serialisation of an element of a key list.
6971
keyListElem :: SerialisedKey -> [Primitive.Vector Word8]
7072
keyListElem (SerialisedKey' keyBytes) = [keySizeBytes, keyBytes] where
7173

@@ -86,14 +88,16 @@ keyListElem (SerialisedKey' keyBytes) = [keySizeBytes, keyBytes] where
8688
appendSingle :: (SerialisedKey, SerialisedKey)
8789
-> IndexOrdinaryAcc s
8890
-> ST s (Maybe Chunk)
89-
appendSingle (firstKey, lastKey) (IndexOrdinaryAcc lastKeys baler)
91+
appendSingle (firstKey, lastKey) (IndexOrdinaryAcc unslicedLastKeys baler)
9092
= assert (firstKey <= lastKey) $
9193
do
9294
#ifdef NO_IGNORE_ASSERTS
93-
maybeLastLastKey <- Growing.readMaybeLast lastKeys
94-
assert (all (< firstKey) maybeLastLastKey) $ return ()
95+
maybeLastUnslicedLastKey <- Growing.readMaybeLast unslicedLastKeys
96+
assert
97+
(all (< firstKey) (fromUnslicedKey <$> maybeLastUnslicedLastKey))
98+
(return ())
9599
#endif
96-
Growing.append lastKeys 1 lastKey
100+
Growing.append unslicedLastKeys 1 (makeUnslicedKey lastKey)
97101
feedBaler (keyListElem lastKey) baler
98102

99103
{-|
@@ -103,13 +107,14 @@ appendSingle (firstKey, lastKey) (IndexOrdinaryAcc lastKeys baler)
103107
appendMulti :: (SerialisedKey, Word32)
104108
-> IndexOrdinaryAcc s
105109
-> ST s [Chunk]
106-
appendMulti (key, overflowPageCount) (IndexOrdinaryAcc lastKeys baler)
110+
appendMulti (key, overflowPageCount) (IndexOrdinaryAcc unslicedLastKeys baler)
107111
= do
108112
#ifdef NO_IGNORE_ASSERTS
109-
maybeLastLastKey <- Growing.readMaybeLast lastKeys
110-
assert (all (< key) maybeLastLastKey) $ return ()
113+
maybeLastUnslicedLastKey <- Growing.readMaybeLast unslicedLastKeys
114+
assert (all (< key) (fromUnslicedKey <$> maybeLastUnslicedLastKey))
115+
(return ())
111116
#endif
112-
Growing.append lastKeys pageCount key
117+
Growing.append unslicedLastKeys pageCount (makeUnslicedKey key)
113118
maybeToList <$> feedBaler keyListElems baler
114119
where
115120

@@ -124,7 +129,7 @@ appendMulti (key, overflowPageCount) (IndexOrdinaryAcc lastKeys baler)
124129
type-agnostic version]('Database.LSMTree.Internal.Index.unsafeEnd').
125130
-}
126131
unsafeEnd :: IndexOrdinaryAcc s -> ST s (Maybe Chunk, IndexOrdinary)
127-
unsafeEnd (IndexOrdinaryAcc lastKeys baler) = do
128-
keys <- Growing.freeze lastKeys
132+
unsafeEnd (IndexOrdinaryAcc unslicedLastKeys baler) = do
133+
frozenUnslicedLastKeys <- Growing.freeze unslicedLastKeys
129134
remnant <- unsafeEndBaler baler
130-
return (remnant, IndexOrdinary keys)
135+
return (remnant, IndexOrdinary frozenUnslicedLastKeys)

0 commit comments

Comments
 (0)