1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_SERVICES_STORAGE_INDEXED_DB_SCOPES_LEVELDB_SCOPES_H_ 6 #define COMPONENTS_SERVICES_STORAGE_INDEXED_DB_SCOPES_LEVELDB_SCOPES_H_ 7 8 #include <stdint.h> 9 #include <limits> 10 #include <list> 11 #include <memory> 12 #include <string> 13 #include <tuple> 14 #include <utility> 15 #include <vector> 16 17 #include "base/callback.h" 18 #include "base/macros.h" 19 #include "base/memory/scoped_refptr.h" 20 #include "base/memory/weak_ptr.h" 21 #include "base/numerics/checked_math.h" 22 #include "base/sequence_checker.h" 23 #include "base/sequenced_task_runner.h" 24 #include "components/services/storage/indexed_db/scopes/leveldb_scopes_coding.h" 25 #include "components/services/storage/indexed_db/scopes/scope_lock.h" 26 #include "components/services/storage/indexed_db/scopes/scope_lock_range.h" 27 #include "third_party/leveldatabase/src/include/leveldb/options.h" 28 #include "third_party/leveldatabase/src/include/leveldb/status.h" 29 30 namespace content { 31 class LevelDBScope; 32 class LevelDBState; 33 class ScopesLockManager; 34 35 class LevelDBScopes { 36 public: 37 using TearDownCallback = base::RepeatingCallback<void(leveldb::Status)>; 38 using EmptyRange = std::pair<std::string, std::string>; 39 static constexpr const size_t kDefaultMaxWriteBatchSizeBytes = 1024 * 1024; 40 41 enum class TaskRunnerMode { 42 // No new sequence runners are created. Both the cleanup and the revert 43 // tasks are run using the sequence runner that is calling this class. 44 kUseCurrentSequence, 45 // A new sequence runner is created for both the cleanup tasks and the 46 // revert tasks. 47 kNewCleanupAndRevertSequences, 48 }; 49 50 // |lock_manager| is expected to be alive during the lifetime of this class. 51 // |tear_down_callback| will not be called after the destruction of this 52 // class. 53 LevelDBScopes(std::vector<uint8_t> metadata_key_prefix, 54 size_t max_write_batch_size_bytes_bytes, 55 scoped_refptr<LevelDBState> level_db, 56 ScopesLockManager* lock_manager, 57 TearDownCallback tear_down_callback); 58 ~LevelDBScopes(); 59 60 // This method needs to be called before any other method on this class. If 61 // unsuccessful, the class cannot be used. Note, this will acquire locks for 62 // the revert tasks if necessary. 63 leveldb::Status Initialize(); 64 65 // This starts (or adopts) the task runners associated with aborting and 66 // cleaning up previous logs based on the given |mode|, and schedules any 67 // pending cleanup or revert tasks. 68 // Returns any errors that might occur during revert if |mode| is 69 // kUseCurrentSequence. 70 leveldb::Status StartRecoveryAndCleanupTasks(TaskRunnerMode mode); 71 72 // In |empty_ranges|, |pair.first| is the inclusive range begin, and 73 // |pair.end| is the exclusive range end. The ranges must be disjoint (they 74 // cannot overlap). 75 std::unique_ptr<LevelDBScope> CreateScope( 76 std::vector<ScopeLock> locks, 77 std::vector<EmptyRange> empty_ranges); 78 79 leveldb::Status Commit(std::unique_ptr<LevelDBScope> scope, 80 bool sync_on_commit); 81 82 // |on_complete| will be called when the cleanup task for the scope has 83 // finished operating. 84 leveldb::Status Commit(std::unique_ptr<LevelDBScope> scope, 85 bool sync_on_commit, 86 base::OnceClosure on_complete); 87 RevertRunnerForTesting()88 base::SequencedTaskRunner* RevertRunnerForTesting() const { 89 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 90 return revert_runner_.get(); 91 } 92 CleanupRunnerForTesting()93 base::SequencedTaskRunner* CleanupRunnerForTesting() const { 94 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 95 return cleanup_runner_.get(); 96 } 97 metadata_key_prefix()98 const std::vector<uint8_t>& metadata_key_prefix() const { 99 return metadata_key_prefix_; 100 } 101 tear_down_callback()102 const TearDownCallback& tear_down_callback() { return tear_down_callback_; } 103 104 private: 105 enum class StartupCleanupType { kExecuteCleanupTasks, kIgnoreCleanupTasks }; 106 using StartupScopeToRevert = std::pair<int64_t, std::vector<ScopeLock>>; 107 using StartupScopeToCleanup = std::pair<int64_t, StartupCleanupType>; 108 using RecoveryLocksList = std::list<std::vector<ScopeLock>>; 109 110 leveldb::Status InitializeGlobalMetadata( 111 const leveldb::ReadOptions& read_options, 112 const leveldb::WriteOptions& write_options); 113 leveldb::Status InitializeScopesAndTasks( 114 const leveldb::ReadOptions& read_options, 115 const leveldb::WriteOptions& write_options); 116 117 // If the mode is TaskRunnerMode::kUseCurrentSequence, then the result of the 118 // revert task is returned. 119 leveldb::Status Rollback(int64_t scope_id, std::vector<ScopeLock> locks); 120 121 void OnCleanupTaskResult(base::OnceClosure on_complete, 122 leveldb::Status result); 123 124 void StartRevertTask(int64_t scope_id, std::vector<ScopeLock> locks); 125 126 void OnRevertTaskResult(int64_t scope_id, 127 std::vector<ScopeLock> locks, 128 leveldb::Status result); 129 130 SEQUENCE_CHECKER(sequence_checker_); 131 const std::vector<uint8_t> metadata_key_prefix_; 132 const size_t max_write_batch_size_bytes_; 133 std::vector<StartupScopeToCleanup> startup_scopes_to_clean_; 134 std::vector<StartupScopeToRevert> startup_scopes_to_revert_; 135 scoped_refptr<base::SequencedTaskRunner> revert_runner_; 136 scoped_refptr<base::SequencedTaskRunner> cleanup_runner_; 137 138 // This gets set to |true| when |Initialize()| succeeds. 139 bool recovery_finished_ = false; 140 int next_scope_id_ = 0; 141 scoped_refptr<LevelDBState> level_db_; 142 // The |lock_manager_| is expected to outlive this class. 143 ScopesLockManager* lock_manager_; 144 TearDownCallback tear_down_callback_; 145 146 #if DCHECK_IS_ON() 147 bool initialize_called_ = false; 148 #endif 149 150 base::WeakPtrFactory<LevelDBScopes> weak_factory_{this}; 151 DISALLOW_COPY_AND_ASSIGN(LevelDBScopes); 152 }; 153 154 } // namespace content 155 156 #endif // COMPONENTS_SERVICES_STORAGE_INDEXED_DB_SCOPES_LEVELDB_SCOPES_H_ 157