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 
10 #pragma once
11 
12 #include "db/version_builder.h"
13 #include "db/version_edit.h"
14 #include "db/version_set.h"
15 
16 namespace ROCKSDB_NAMESPACE {
17 
18 typedef std::unique_ptr<BaseReferencedVersionBuilder> VersionBuilderUPtr;
19 
20 // A class used for scanning MANIFEST file.
21 // VersionEditHandler reads a MANIFEST file, parses the version edits, and
22 // builds the version set's in-memory state, e.g. the version storage info for
23 // the versions of column families.
24 // To use this class and its subclasses,
25 // 1. Create an object of VersionEditHandler or its subclasses.
26 //    VersionEditHandler handler(read_only, column_families, version_set,
27 //                               track_missing_files, ignore_missing_files);
28 // 2. Status s = handler.Iterate(reader, &db_id);
29 // 3. Check s and handle possible errors.
30 //
31 // Not thread-safe, external synchronization is necessary if an object of
32 // VersionEditHandler is shared by multiple threads.
33 class VersionEditHandler {
34  public:
35   explicit VersionEditHandler(
36       bool read_only,
37       const std::vector<ColumnFamilyDescriptor>& column_families,
38       VersionSet* version_set, bool track_missing_files,
39       bool ignore_missing_files);
40 
~VersionEditHandler()41   virtual ~VersionEditHandler() {}
42 
43   Status Iterate(log::Reader& reader, std::string* db_id);
44 
status()45   const Status& status() const { return status_; }
46 
47   bool HasMissingFiles() const;
48 
49  protected:
50   Status ApplyVersionEdit(VersionEdit& edit, ColumnFamilyData** cfd);
51 
52   Status OnColumnFamilyAdd(VersionEdit& edit, ColumnFamilyData** cfd);
53 
54   Status OnColumnFamilyDrop(VersionEdit& edit, ColumnFamilyData** cfd);
55 
56   Status OnNonCfOperation(VersionEdit& edit, ColumnFamilyData** cfd);
57 
58   Status Initialize();
59 
60   void CheckColumnFamilyId(const VersionEdit& edit, bool* cf_in_not_found,
61                            bool* cf_in_builders) const;
62 
63   virtual void CheckIterationResult(const log::Reader& reader, Status* s);
64 
65   ColumnFamilyData* CreateCfAndInit(const ColumnFamilyOptions& cf_options,
66                                     const VersionEdit& edit);
67 
68   virtual ColumnFamilyData* DestroyCfAndCleanup(const VersionEdit& edit);
69 
70   virtual Status MaybeCreateVersion(const VersionEdit& edit,
71                                     ColumnFamilyData* cfd,
72                                     bool force_create_version);
73 
74   Status LoadTables(ColumnFamilyData* cfd,
75                     bool prefetch_index_and_filter_in_cache,
76                     bool is_initial_load);
77 
78   const bool read_only_;
79   const std::vector<ColumnFamilyDescriptor>& column_families_;
80   Status status_;
81   VersionSet* version_set_;
82   AtomicGroupReadBuffer read_buffer_;
83   std::unordered_map<uint32_t, VersionBuilderUPtr> builders_;
84   std::unordered_map<std::string, ColumnFamilyOptions> name_to_options_;
85   std::unordered_map<uint32_t, std::string> column_families_not_found_;
86   VersionEditParams version_edit_params_;
87   const bool track_missing_files_;
88   std::unordered_map<uint32_t, std::unordered_set<uint64_t>>
89       cf_to_missing_files_;
90   bool no_error_if_table_files_missing_;
91 
92  private:
93   Status ExtractInfoFromVersionEdit(ColumnFamilyData* cfd,
94                                     const VersionEdit& edit);
95 
96   bool initialized_;
97 };
98 
99 // A class similar to its base class, i.e. VersionEditHandler.
100 // VersionEditHandlerPointInTime restores the versions to the most recent point
101 // in time such that at this point, the version does not have missing files.
102 //
103 // Not thread-safe, external synchronization is necessary if an object of
104 // VersionEditHandlerPointInTime is shared by multiple threads.
105 class VersionEditHandlerPointInTime : public VersionEditHandler {
106  public:
107   VersionEditHandlerPointInTime(
108       bool read_only,
109       const std::vector<ColumnFamilyDescriptor>& column_families,
110       VersionSet* version_set);
111   ~VersionEditHandlerPointInTime() override;
112 
113  protected:
114   void CheckIterationResult(const log::Reader& reader, Status* s) override;
115   ColumnFamilyData* DestroyCfAndCleanup(const VersionEdit& edit) override;
116   Status MaybeCreateVersion(const VersionEdit& edit, ColumnFamilyData* cfd,
117                             bool force_create_version) override;
118 
119  private:
120   std::unordered_map<uint32_t, Version*> versions_;
121 };
122 
123 }  // namespace ROCKSDB_NAMESPACE
124