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 #pragma once
6 
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "db/builder.h"
13 #include "db/table_properties_collector.h"
14 #include "rocksdb/comparator.h"
15 #include "rocksdb/memory_allocator.h"
16 #include "rocksdb/options.h"
17 #include "rocksdb/slice.h"
18 #include "table/block_based/block_builder.h"
19 #include "table/block_based/block_type.h"
20 #include "table/format.h"
21 #include "util/kv_map.h"
22 
23 namespace ROCKSDB_NAMESPACE {
24 
25 class BlockBuilder;
26 class BlockHandle;
27 class Env;
28 class Footer;
29 class Logger;
30 class RandomAccessFile;
31 struct TableProperties;
32 
33 class MetaIndexBuilder {
34  public:
35   MetaIndexBuilder(const MetaIndexBuilder&) = delete;
36   MetaIndexBuilder& operator=(const MetaIndexBuilder&) = delete;
37 
38   MetaIndexBuilder();
39   void Add(const std::string& key, const BlockHandle& handle);
40 
41   // Write all the added key/value pairs to the block and return the contents
42   // of the block.
43   Slice Finish();
44 
45  private:
46   // store the sorted key/handle of the metablocks.
47   stl_wrappers::KVMap meta_block_handles_;
48   std::unique_ptr<BlockBuilder> meta_index_block_;
49 };
50 
51 class PropertyBlockBuilder {
52  public:
53   PropertyBlockBuilder(const PropertyBlockBuilder&) = delete;
54   PropertyBlockBuilder& operator=(const PropertyBlockBuilder&) = delete;
55 
56   PropertyBlockBuilder();
57 
58   void AddTableProperty(const TableProperties& props);
59   void Add(const std::string& key, uint64_t value);
60   void Add(const std::string& key, const std::string& value);
61   void Add(const UserCollectedProperties& user_collected_properties);
62 
63   // Write all the added entries to the block and return the block contents
64   Slice Finish();
65 
66  private:
67   std::unique_ptr<BlockBuilder> properties_block_;
68   stl_wrappers::KVMap props_;
69 };
70 
71 // Were we encounter any error occurs during user-defined statistics collection,
72 // we'll write the warning message to info log.
73 void LogPropertiesCollectionError(
74     Logger* info_log, const std::string& method, const std::string& name);
75 
76 // Utility functions help table builder to trigger batch events for user
77 // defined property collectors.
78 // Return value indicates if there is any error occurred; if error occurred,
79 // the warning message will be logged.
80 // NotifyCollectTableCollectorsOnAdd() triggers the `Add` event for all
81 // property collectors.
82 bool NotifyCollectTableCollectorsOnAdd(
83     const Slice& key, const Slice& value, uint64_t file_size,
84     const std::vector<std::unique_ptr<IntTblPropCollector>>& collectors,
85     Logger* info_log);
86 
87 void NotifyCollectTableCollectorsOnBlockAdd(
88     const std::vector<std::unique_ptr<IntTblPropCollector>>& collectors,
89     uint64_t blockRawBytes, uint64_t blockCompressedBytesFast,
90     uint64_t blockCompressedBytesSlow);
91 
92 // NotifyCollectTableCollectorsOnFinish() triggers the `Finish` event for all
93 // property collectors. The collected properties will be added to `builder`.
94 bool NotifyCollectTableCollectorsOnFinish(
95     const std::vector<std::unique_ptr<IntTblPropCollector>>& collectors,
96     Logger* info_log, PropertyBlockBuilder* builder);
97 
98 // Read the properties from the table.
99 // @returns a status to indicate if the operation succeeded. On success,
100 //          *table_properties will point to a heap-allocated TableProperties
101 //          object, otherwise value of `table_properties` will not be modified.
102 Status ReadProperties(const Slice& handle_value, RandomAccessFileReader* file,
103                       FilePrefetchBuffer* prefetch_buffer, const Footer& footer,
104                       const ImmutableCFOptions& ioptions,
105                       TableProperties** table_properties, bool verify_checksum,
106                       BlockHandle* block_handle,
107                       CacheAllocationPtr* verification_buf,
108                       bool compression_type_missing = false,
109                       MemoryAllocator* memory_allocator = nullptr);
110 
111 // Directly read the properties from the properties block of a plain table.
112 // @returns a status to indicate if the operation succeeded. On success,
113 //          *table_properties will point to a heap-allocated TableProperties
114 //          object, otherwise value of `table_properties` will not be modified.
115 // certain tables do not have compression_type byte setup properly for
116 // uncompressed blocks, caller can request to reset compression type by
117 // passing compression_type_missing = true, the same applies to
118 // `ReadProperties`, `FindMetaBlock`, and `ReadMetaBlock`
119 Status ReadTableProperties(RandomAccessFileReader* file, uint64_t file_size,
120                            uint64_t table_magic_number,
121                            const ImmutableCFOptions& ioptions,
122                            TableProperties** properties,
123                            bool compression_type_missing = false,
124                            MemoryAllocator* memory_allocator = nullptr);
125 
126 // Find the meta block from the meta index block.
127 Status FindMetaBlock(InternalIterator* meta_index_iter,
128                      const std::string& meta_block_name,
129                      BlockHandle* block_handle);
130 
131 // Find the meta block
132 Status FindMetaBlock(RandomAccessFileReader* file, uint64_t file_size,
133                      uint64_t table_magic_number,
134                      const ImmutableCFOptions& ioptions,
135                      const std::string& meta_block_name,
136                      BlockHandle* block_handle,
137                      bool compression_type_missing = false,
138                      MemoryAllocator* memory_allocator = nullptr);
139 
140 // Read the specified meta block with name meta_block_name
141 // from `file` and initialize `contents` with contents of this block.
142 // Return Status::OK in case of success.
143 Status ReadMetaBlock(RandomAccessFileReader* file,
144                      FilePrefetchBuffer* prefetch_buffer, uint64_t file_size,
145                      uint64_t table_magic_number,
146                      const ImmutableCFOptions& ioptions,
147                      const std::string& meta_block_name, BlockType block_type,
148                      BlockContents* contents,
149                      bool compression_type_missing = false,
150                      MemoryAllocator* memory_allocator = nullptr);
151 
152 }  // namespace ROCKSDB_NAMESPACE
153