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 #pragma once
7 
8 #ifndef ROCKSDB_LITE
9 #include <stdint.h>
10 #include <string>
11 #include <vector>
12 #include "db/version_edit.h"
13 #include "rocksdb/options.h"
14 #include "rocksdb/status.h"
15 #include "rocksdb/table.h"
16 #include "rocksdb/table_properties.h"
17 #include "table/plain/plain_table_bloom.h"
18 #include "table/plain/plain_table_index.h"
19 #include "table/plain/plain_table_key_coding.h"
20 #include "table/table_builder.h"
21 
22 namespace ROCKSDB_NAMESPACE {
23 
24 class BlockBuilder;
25 class BlockHandle;
26 class WritableFile;
27 class TableBuilder;
28 
29 // The builder class of PlainTable. For description of PlainTable format
30 // See comments of class PlainTableFactory, where instances of
31 // PlainTableReader are created.
32 class PlainTableBuilder: public TableBuilder {
33  public:
34   // Create a builder that will store the contents of the table it is
35   // building in *file.  Does not close the file.  It is up to the
36   // caller to close the file after calling Finish(). The output file
37   // will be part of level specified by 'level'.  A value of -1 means
38   // that the caller does not know which level the output file will reside.
39   PlainTableBuilder(
40       const ImmutableCFOptions& ioptions, const MutableCFOptions& moptions,
41       const std::vector<std::unique_ptr<IntTblPropCollectorFactory>>*
42           int_tbl_prop_collector_factories,
43       uint32_t column_family_id, WritableFileWriter* file,
44       uint32_t user_key_size, EncodingType encoding_type,
45       size_t index_sparseness, uint32_t bloom_bits_per_key,
46       const std::string& column_family_name, uint32_t num_probes = 6,
47       size_t huge_page_tlb_size = 0, double hash_table_ratio = 0,
48       bool store_index_in_file = false);
49   // No copying allowed
50   PlainTableBuilder(const PlainTableBuilder&) = delete;
51   void operator=(const PlainTableBuilder&) = delete;
52 
53   // REQUIRES: Either Finish() or Abandon() has been called.
54   ~PlainTableBuilder();
55 
56   // Add key,value to the table being constructed.
57   // REQUIRES: key is after any previously added key according to comparator.
58   // REQUIRES: Finish(), Abandon() have not been called
59   void Add(const Slice& key, const Slice& value) override;
60 
61   // Return non-ok iff some error has been detected.
status()62   Status status() const override { return status_; }
63 
64   // Return non-ok iff some error happens during IO.
io_status()65   IOStatus io_status() const override { return io_status_; }
66 
67   // Finish building the table.  Stops using the file passed to the
68   // constructor after this function returns.
69   // REQUIRES: Finish(), Abandon() have not been called
70   Status Finish() override;
71 
72   // Indicate that the contents of this builder should be abandoned.  Stops
73   // using the file passed to the constructor after this function returns.
74   // If the caller is not going to call Finish(), it must call Abandon()
75   // before destroying this builder.
76   // REQUIRES: Finish(), Abandon() have not been called
77   void Abandon() override;
78 
79   // Number of calls to Add() so far.
80   uint64_t NumEntries() const override;
81 
82   // Size of the file generated so far.  If invoked after a successful
83   // Finish() call, returns the size of the final generated file.
84   uint64_t FileSize() const override;
85 
GetTableProperties()86   TableProperties GetTableProperties() const override { return properties_; }
87 
SaveIndexInFile()88   bool SaveIndexInFile() const { return store_index_in_file_; }
89 
90   // Get file checksum
91   std::string GetFileChecksum() const override;
92 
93   // Get file checksum function name
94   const char* GetFileChecksumFuncName() const override;
95 
96  private:
97   Arena arena_;
98   const ImmutableCFOptions& ioptions_;
99   const MutableCFOptions& moptions_;
100   std::vector<std::unique_ptr<IntTblPropCollector>>
101       table_properties_collectors_;
102 
103   BloomBlockBuilder bloom_block_;
104   std::unique_ptr<PlainTableIndexBuilder> index_builder_;
105 
106   WritableFileWriter* file_;
107   uint64_t offset_ = 0;
108   uint32_t bloom_bits_per_key_;
109   size_t huge_page_tlb_size_;
110   Status status_;
111   IOStatus io_status_;
112   TableProperties properties_;
113   PlainTableKeyEncoder encoder_;
114 
115   bool store_index_in_file_;
116 
117   std::vector<uint32_t> keys_or_prefixes_hashes_;
118   bool closed_ = false;  // Either Finish() or Abandon() has been called.
119 
120   const SliceTransform* prefix_extractor_;
121 
GetPrefix(const Slice & target)122   Slice GetPrefix(const Slice& target) const {
123     assert(target.size() >= 8);  // target is internal key
124     return GetPrefixFromUserKey(GetUserKey(target));
125   }
126 
GetPrefix(const ParsedInternalKey & target)127   Slice GetPrefix(const ParsedInternalKey& target) const {
128     return GetPrefixFromUserKey(target.user_key);
129   }
130 
GetUserKey(const Slice & key)131   Slice GetUserKey(const Slice& key) const {
132     return Slice(key.data(), key.size() - 8);
133   }
134 
GetPrefixFromUserKey(const Slice & user_key)135   Slice GetPrefixFromUserKey(const Slice& user_key) const {
136     if (!IsTotalOrderMode()) {
137       return prefix_extractor_->Transform(user_key);
138     } else {
139       // Use empty slice as prefix if prefix_extractor is not set.
140       // In that case,
141       // it falls back to pure binary search and
142       // total iterator seek is supported.
143       return Slice();
144     }
145   }
146 
IsTotalOrderMode()147   bool IsTotalOrderMode() const { return (prefix_extractor_ == nullptr); }
148 };
149 
150 }  // namespace ROCKSDB_NAMESPACE
151 
152 #endif  // ROCKSDB_LITE
153