1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_INDEXED_DB_INSTANCE_LEVELDB_INDEXED_DB_LEVELDB_OPERATIONS_H_
#define CONTENT_BROWSER_INDEXED_DB_INSTANCE_LEVELDB_INDEXED_DB_LEVELDB_OPERATIONS_H_
#include <memory>
#include <string>
#include <string_view>
#include "base/files/file_path.h"
#include "base/time/time.h"
#include "components/services/storage/indexed_db/transactional_leveldb/leveldb_write_batch.h"
#include "content/browser/indexed_db/indexed_db_data_loss_info.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/status.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h"
#include "third_party/leveldatabase/src/include/leveldb/comparator.h"
// Contains common operations for LevelDBTransactions and/or LevelDBDatabases.
namespace storage {
struct BucketLocator;
} // namespace storage
namespace content::indexed_db {
class TransactionalLevelDBDatabase;
class TransactionalLevelDBIterator;
class TransactionalLevelDBTransaction;
class LevelDBDirectTransaction;
base::FilePath ComputeCorruptionFileName(
const storage::BucketLocator& bucket_locator);
// If a corruption file for the given `storage_key` at the given |path_base|
// exists it is deleted, and the message is returned. If the file does not
// exist, or if there is an error parsing the message, then this method returns
// an empty string (and deletes the file).
std::string CONTENT_EXPORT
ReadCorruptionInfo(const base::FilePath& path_base,
const storage::BucketLocator& bucket_locator);
bool RecordCorruptionInfo(const base::FilePath& path_base,
const storage::BucketLocator& bucket_locator,
const std::string& message);
// Was able to use LevelDB to read the data w/o error, but the data read was not
// in the expected format.
Status CONTENT_EXPORT InternalInconsistencyStatus();
Status InvalidDBKeyStatus();
template <typename Transaction>
Status PutValue(Transaction* transaction,
std::string_view key,
std::string* value) {
return Status(transaction->Put(key, value));
}
// This function must be declared as 'inline' to avoid duplicate symbols.
template <>
inline Status PutValue(LevelDBWriteBatch* write_batch,
std::string_view key,
std::string* value) {
write_batch->Put(key, std::string_view(*value));
return Status::OK();
}
// Note - this uses DecodeInt, which is a 'dumb' varint decoder. See DecodeInt.
template <typename DBOrTransaction>
Status GetInt(DBOrTransaction* db,
std::string_view key,
int64_t* found_int,
bool* found) {
std::string result;
Status s(db->Get(key, &result, found));
if (!s.ok()) {
return s;
}
if (!*found) {
return Status::OK();
}
std::string_view slice(result);
if (DecodeInt(&slice, found_int) && slice.empty()) {
return s;
}
return InternalInconsistencyStatus();
}
[[nodiscard]] Status PutBool(TransactionalLevelDBTransaction* transaction,
std::string_view key,
bool value);
// Note - this uses EncodeInt, which is a 'dumb' varint encoder. See EncodeInt.
template <typename TransactionOrWriteBatch>
[[nodiscard]] Status PutInt(TransactionOrWriteBatch* transaction_or_write_batch,
std::string_view key,
int64_t value) {
DCHECK_GE(value, 0);
std::string buffer;
EncodeInt(value, &buffer);
return PutValue(transaction_or_write_batch, key, &buffer);
}
template <typename DBOrTransaction>
[[nodiscard]] Status GetVarInt(DBOrTransaction* db,
std::string_view key,
int64_t* found_int,
bool* found);
template <typename TransactionOrWriteBatch>
[[nodiscard]] Status PutVarInt(TransactionOrWriteBatch* transaction,
std::string_view key,
int64_t value);
template <typename DBOrTransaction>
[[nodiscard]] Status GetString(DBOrTransaction* db,
std::string_view key,
std::u16string* found_string,
bool* found);
[[nodiscard]] Status PutString(TransactionalLevelDBTransaction* transaction,
std::string_view key,
const std::u16string& value);
[[nodiscard]] Status PutIDBKeyPath(TransactionalLevelDBTransaction* transaction,
std::string_view key,
const blink::IndexedDBKeyPath& value);
template <typename DBOrTransaction>
[[nodiscard]] Status GetMaxObjectStoreId(DBOrTransaction* db,
int64_t database_id,
int64_t* max_object_store_id);
[[nodiscard]] Status SetMaxObjectStoreId(
TransactionalLevelDBTransaction* transaction,
int64_t database_id,
int64_t object_store_id);
[[nodiscard]] Status GetNewVersionNumber(
TransactionalLevelDBTransaction* transaction,
int64_t database_id,
int64_t object_store_id,
int64_t* new_version_number);
[[nodiscard]] Status SetMaxIndexId(TransactionalLevelDBTransaction* transaction,
int64_t database_id,
int64_t object_store_id,
int64_t index_id);
[[nodiscard]] Status VersionExists(TransactionalLevelDBTransaction* transaction,
int64_t database_id,
int64_t object_store_id,
int64_t version,
const std::string& encoded_primary_key,
bool* exists);
[[nodiscard]] Status GetNewDatabaseId(LevelDBDirectTransaction* transaction,
int64_t* new_id);
[[nodiscard]] bool CheckObjectStoreAndMetaDataType(
const TransactionalLevelDBIterator* it,
const std::string& stop_key,
int64_t object_store_id,
int64_t meta_data_type);
[[nodiscard]] bool CheckIndexAndMetaDataKey(
const TransactionalLevelDBIterator* it,
const std::string& stop_key,
int64_t index_id,
unsigned char meta_data_type);
[[nodiscard]] bool FindGreatestKeyLessThanOrEqual(
TransactionalLevelDBTransaction* transaction,
const std::string& target,
std::string* found_key,
Status* s);
[[nodiscard]] bool GetBlobNumberGeneratorCurrentNumber(
LevelDBDirectTransaction* leveldb_transaction,
int64_t database_id,
int64_t* blob_number_generator_current_number);
[[nodiscard]] bool UpdateBlobNumberGeneratorCurrentNumber(
LevelDBDirectTransaction* leveldb_transaction,
int64_t database_id,
int64_t blob_number_generator_current_number);
// Maximum time delays for tombstone sweeping and compaction tasks, throttled on
// global and per-bucket frequencies, triggered by backing store close.
inline constexpr base::TimeDelta kMaxGlobalSweepDelay = base::Hours(1);
inline constexpr base::TimeDelta kMaxBucketSweepDelay = base::Days(3);
inline constexpr base::TimeDelta kMaxGlobalCompactionDelay = base::Hours(1);
inline constexpr base::TimeDelta kMaxBucketCompactionDelay = base::Days(3);
// Get or update the earliest tombstone sweeping and compaction times, using
// global and per-bucket delays.
base::Time GetEarliestSweepTime(TransactionalLevelDBDatabase* db);
Status UpdateEarliestSweepTime(LevelDBDirectTransaction* txn);
base::Time GetEarliestCompactionTime(TransactionalLevelDBDatabase* db);
Status UpdateEarliestCompactionTime(LevelDBDirectTransaction* txn);
// Initialize global times for compaction and tombstone sweeping.
void InitializeGlobalSweepAndCompactionTimes();
// Forcibly reset global times for compaction and tombstone sweeping for tests.
CONTENT_EXPORT void ResetGlobalSweepAndCompactionTimesForTest();
CONTENT_EXPORT const leveldb::Comparator* GetDefaultLevelDBComparator();
} // namespace content::indexed_db
#endif // CONTENT_BROWSER_INDEXED_DB_INSTANCE_LEVELDB_INDEXED_DB_LEVELDB_OPERATIONS_H_
|