|
| 1 | +{-# LANGUAGE TypeFamilies #-} |
| 2 | + |
| 3 | +{-| |
| 4 | + Provides a common interface to different types of fence pointer indexes and |
| 5 | + their accumulators. |
| 6 | +-} |
| 7 | +module Database.LSMTree.Internal.Index |
| 8 | +( |
| 9 | + Index (search, sizeInPages, fromSBS), |
| 10 | + IndexAcc (ResultingIndex, appendSingle, appendMulti, unsafeEnd) |
| 11 | +) |
| 12 | +where |
| 13 | + |
| 14 | +import Control.Monad.ST.Strict (ST) |
| 15 | +import Data.ByteString.Short (ShortByteString) |
| 16 | +import Data.Word (Word32) |
| 17 | +import Database.LSMTree.Internal.Chunk (Chunk) |
| 18 | +import Database.LSMTree.Internal.Entry (NumEntries) |
| 19 | +import Database.LSMTree.Internal.Page (NumPages, PageSpan) |
| 20 | +import Database.LSMTree.Internal.Serialise (SerialisedKey) |
| 21 | + |
| 22 | +-- | The class of index types. |
| 23 | +class Index i where |
| 24 | + |
| 25 | + {-| |
| 26 | + Searches for a page span that contains a key–value pair with the given |
| 27 | + key. If there is indeed such a pair, the result is the corresponding |
| 28 | + page span; if there is no such pair, the result is an arbitrary but |
| 29 | + valid page span. |
| 30 | + -} |
| 31 | + search :: SerialisedKey -> i -> PageSpan |
| 32 | + |
| 33 | + -- | Yields the number of pages covered by an index. |
| 34 | + sizeInPages :: i -> NumPages |
| 35 | + |
| 36 | + {-| |
| 37 | + Reads an index along with the number of entries of the respective run |
| 38 | + from a byte string. |
| 39 | +
|
| 40 | + The byte string must contain the serialised index exactly, with no |
| 41 | + leading or trailing space. Furthermore, its contents must be stored |
| 42 | + 64-bit-aligned. |
| 43 | +
|
| 44 | + The contents of the byte string may be directly used as the backing |
| 45 | + memory for the constructed index. Currently, this is done for compact |
| 46 | + indexes. |
| 47 | +
|
| 48 | + For deserialising numbers, the endianness of the host system is used. If |
| 49 | + serialisation has been done with a different endianness, this mismatch |
| 50 | + is detected by looking at the type–version indicator. |
| 51 | + -} |
| 52 | + fromSBS :: ShortByteString -> Either String (NumEntries, i) |
| 53 | + |
| 54 | +{-| |
| 55 | + The class of index accumulator types, where an index accumulator denotes an |
| 56 | + index under incremental construction. |
| 57 | +
|
| 58 | + Incremental index construction is only guaranteed to work correctly when the |
| 59 | + following conditions are met: |
| 60 | +
|
| 61 | + * The supplied key ranges do not overlap and are given in ascending order. |
| 62 | +
|
| 63 | + * Each supplied key is at least 8 and at most 65535 bytes long. |
| 64 | + (Currently, construction of compact indexes needs the former and |
| 65 | + construction of ordinary indexes needs the latter bound.) |
| 66 | +-} |
| 67 | +class Index (ResultingIndex j) => IndexAcc j where |
| 68 | + |
| 69 | + -- | The type of indexes constructed by accumulators of a certain type |
| 70 | + type ResultingIndex j |
| 71 | + |
| 72 | + {-| |
| 73 | + Adds information about a single page that fully comprises one or more |
| 74 | + key–value pairs to an index and outputs newly available chunks. |
| 75 | +
|
| 76 | + See the documentation of the 'IndexAcc' class for constraints to adhere |
| 77 | + to. |
| 78 | + -} |
| 79 | + appendSingle :: (SerialisedKey, SerialisedKey) -> j s -> ST s (Maybe Chunk) |
| 80 | + |
| 81 | + {-| |
| 82 | + Adds information about multiple pages that together comprise a single |
| 83 | + key–value pair to an index and outputs newly available chunks. |
| 84 | +
|
| 85 | + The provided 'Word32' value denotes the number of /overflow/ pages, so |
| 86 | + that the number of pages that comprise the key–value pair is the |
| 87 | + successor of that number. |
| 88 | +
|
| 89 | + See the documentation of the 'IndexAcc' class for constraints to adhere |
| 90 | + to. |
| 91 | + -} |
| 92 | + appendMulti :: (SerialisedKey, Word32) -> j s -> ST s [Chunk] |
| 93 | + |
| 94 | + {-| |
| 95 | + Returns the constructed index, along with a final chunk in case the |
| 96 | + serialised key list has not been fully output yet, thereby invalidating |
| 97 | + the index under construction. Executing @unsafeEnd index@ is only safe |
| 98 | + when @index@ is not used afterwards. |
| 99 | + -} |
| 100 | + unsafeEnd :: j s -> ST s (Maybe Chunk, ResultingIndex j) |
0 commit comments