block_based_table_builder.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #pragma once
  10. #include <stdint.h>
  11. #include <array>
  12. #include <limits>
  13. #include <string>
  14. #include <utility>
  15. #include <vector>
  16. #include "db/version_edit.h"
  17. #include "rocksdb/flush_block_policy.h"
  18. #include "rocksdb/listener.h"
  19. #include "rocksdb/options.h"
  20. #include "rocksdb/status.h"
  21. #include "rocksdb/table.h"
  22. #include "table/meta_blocks.h"
  23. #include "table/table_builder.h"
  24. #include "util/atomic.h"
  25. #include "util/compression.h"
  26. namespace ROCKSDB_NAMESPACE {
  27. class BlockBuilder;
  28. class BlockHandle;
  29. class WritableFile;
  30. struct BlockBasedTableOptions;
  31. extern const uint64_t kBlockBasedTableMagicNumber;
  32. extern const uint64_t kLegacyBlockBasedTableMagicNumber;
  33. class BlockBasedTableBuilder : public TableBuilder {
  34. public:
  35. // Create a builder that will store the contents of the table it is
  36. // building in *file. Does not close the file. It is up to the
  37. // caller to close the file after calling Finish().
  38. BlockBasedTableBuilder(const BlockBasedTableOptions& table_options,
  39. const TableBuilderOptions& table_builder_options,
  40. WritableFileWriter* file);
  41. // No copying allowed
  42. BlockBasedTableBuilder(const BlockBasedTableBuilder&) = delete;
  43. BlockBasedTableBuilder& operator=(const BlockBasedTableBuilder&) = delete;
  44. // REQUIRES: Either Finish() or Abandon() has been called.
  45. ~BlockBasedTableBuilder();
  46. // Add key,value to the table being constructed.
  47. // REQUIRES: Unless key has type kTypeRangeDeletion, key is after any
  48. // previously added non-kTypeRangeDeletion key according to
  49. // comparator.
  50. // REQUIRES: Finish(), Abandon() have not been called
  51. void Add(const Slice& key, const Slice& value) override;
  52. // Return non-ok iff some error has been detected.
  53. Status status() const override;
  54. // Return non-ok iff some error happens during IO.
  55. IOStatus io_status() const override;
  56. // Finish building the table. Stops using the file passed to the
  57. // constructor after this function returns.
  58. // REQUIRES: Finish(), Abandon() have not been called
  59. Status Finish() override;
  60. // Indicate that the contents of this builder should be abandoned. Stops
  61. // using the file passed to the constructor after this function returns.
  62. // If the caller is not going to call Finish(), it must call Abandon()
  63. // before destroying this builder.
  64. // REQUIRES: Finish(), Abandon() have not been called
  65. void Abandon() override;
  66. // Number of calls to Add() so far.
  67. uint64_t NumEntries() const override;
  68. bool IsEmpty() const override;
  69. uint64_t PreCompressionSize() const override;
  70. // Size of the file generated so far. If invoked after a successful
  71. // Finish() call, returns the size of the final generated file.
  72. uint64_t FileSize() const override;
  73. // Estimated size of the file generated so far. This is used when
  74. // FileSize() cannot estimate final SST size, e.g. parallel compression
  75. // is enabled.
  76. uint64_t EstimatedFileSize() const override;
  77. // Get the size of the "tail" part of a SST file. "Tail" refers to
  78. // all blocks after data blocks till the end of the SST file.
  79. uint64_t GetTailSize() const override;
  80. bool NeedCompact() const override;
  81. // Get table properties
  82. TableProperties GetTableProperties() const override;
  83. // Get file checksum
  84. std::string GetFileChecksum() const override;
  85. // Get file checksum function name
  86. const char* GetFileChecksumFuncName() const override;
  87. void SetSeqnoTimeTableProperties(const SeqnoToTimeMapping& relevant_mapping,
  88. uint64_t oldest_ancestor_time) override;
  89. uint64_t GetWorkerCPUMicros() const override;
  90. private:
  91. bool ok() const;
  92. // Transition state from buffered to unbuffered if the conditions are met. See
  93. // `Rep::State` API comment for details of the states.
  94. // REQUIRES: `rep_->state == kBuffered`
  95. void MaybeEnterUnbuffered(const Slice* first_key_in_next_block);
  96. // Try to keep some parallel-specific code separate to improve hot code
  97. // locality for non-parallel case
  98. void EmitBlock(std::string& uncompressed,
  99. const Slice& last_key_in_current_block,
  100. const Slice* first_key_in_next_block);
  101. void EmitBlockForParallel(std::string& uncompressed,
  102. const Slice& last_key_in_current_block,
  103. const Slice* first_key_in_next_block);
  104. // Compress and write block content to the file, from a single-threaded
  105. // context
  106. // @skip_delta_encoding : This is set to non null for data blocks, so that
  107. // caller would know whether the index entry of this data block should
  108. // skip delta encoding or not
  109. void WriteBlock(const Slice& block_contents, BlockHandle* handle,
  110. BlockType block_type, bool* skip_delta_encoding = nullptr);
  111. // Directly write data to the file.
  112. void WriteMaybeCompressedBlock(const Slice& block_contents, CompressionType,
  113. BlockHandle* handle, BlockType block_type,
  114. const Slice* uncompressed_block_data = nullptr,
  115. bool* skip_delta_encoding = nullptr);
  116. IOStatus WriteMaybeCompressedBlockImpl(
  117. const Slice& block_contents, CompressionType, BlockHandle* handle,
  118. BlockType block_type, const Slice* uncompressed_block_data = nullptr,
  119. bool* skip_delta_encoding = nullptr);
  120. void SetupCacheKeyPrefix(const TableBuilderOptions& tbo);
  121. template <typename TBlocklike>
  122. Status InsertBlockInCache(const Slice& block_contents,
  123. const BlockHandle* handle, BlockType block_type);
  124. Status InsertBlockInCacheHelper(const Slice& block_contents,
  125. const BlockHandle* handle,
  126. BlockType block_type);
  127. Status InsertBlockInCompressedCache(const Slice& block_contents,
  128. const CompressionType type,
  129. const BlockHandle* handle);
  130. void WriteFilterBlock(MetaIndexBuilder* meta_index_builder);
  131. void WriteIndexBlock(MetaIndexBuilder* meta_index_builder,
  132. BlockHandle* index_block_handle);
  133. void WritePropertiesBlock(MetaIndexBuilder* meta_index_builder);
  134. void WriteCompressionDictBlock(MetaIndexBuilder* meta_index_builder);
  135. void WriteRangeDelBlock(MetaIndexBuilder* meta_index_builder);
  136. void WriteFooter(BlockHandle& metaindex_block_handle,
  137. BlockHandle& index_block_handle);
  138. struct Rep;
  139. class BlockBasedTablePropertiesCollectorFactory;
  140. class BlockBasedTablePropertiesCollector;
  141. std::unique_ptr<Rep> rep_;
  142. struct WorkingAreaPair;
  143. struct ParallelCompressionRep;
  144. // Advanced operation: flush any buffered key/value pairs to file.
  145. // Can be used to ensure that two adjacent entries never live in
  146. // the same data block. Most clients should not need to use this method.
  147. // REQUIRES: Finish(), Abandon() have not been called
  148. void Flush(const Slice* first_key_in_next_block);
  149. // Some compression libraries fail when the uncompressed size is bigger than
  150. // int. If uncompressed size is bigger than kCompressionSizeLimit, don't
  151. // compress it
  152. const uint64_t kCompressionSizeLimit = std::numeric_limits<int>::max();
  153. // Code for a "parallel compression" worker thread, which can really do SST
  154. // writes and block compressions alternately.
  155. void BGWorker(WorkingAreaPair& working_area);
  156. // Given uncompressed block content, try to compress it and return result and
  157. // compression type
  158. Status CompressAndVerifyBlock(const Slice& uncompressed_block_data,
  159. bool is_data_block,
  160. WorkingAreaPair& working_area,
  161. GrowableBuffer* compressed_output,
  162. CompressionType* result_compression_type);
  163. // If configured, start worker threads for parallel compression
  164. void MaybeStartParallelCompression();
  165. // Stop worker threads for parallel compression
  166. void StopParallelCompression(bool abort);
  167. };
  168. } // namespace ROCKSDB_NAMESPACE