Add strongly typed FileDbId.
GitOrigin-RevId: 234c9ec0ecda3f2ba48e0fd00fa06a8ec0188ca4
This commit is contained in:
parent
5438119bb4
commit
60e4d27011
@ -482,6 +482,7 @@ set(TDLIB_SOURCE
|
||||
td/telegram/DraftMessage.h
|
||||
td/telegram/files/FileBitmask.h
|
||||
td/telegram/files/FileDb.h
|
||||
td/telegram/files/FileDbId.h
|
||||
td/telegram/files/FileDownloader.h
|
||||
td/telegram/files/FileEncryptionKey.h
|
||||
td/telegram/files/FileFromBytes.h
|
||||
|
@ -59,8 +59,7 @@ class FileDb : public FileDbInterface {
|
||||
public:
|
||||
class FileDbActor : public Actor {
|
||||
public:
|
||||
using Id = FileDbInterface::Id;
|
||||
FileDbActor(Id current_pmc_id, std::shared_ptr<SqliteKeyValueSafe> file_kv_safe)
|
||||
FileDbActor(FileDbId current_pmc_id, std::shared_ptr<SqliteKeyValueSafe> file_kv_safe)
|
||||
: current_pmc_id_(current_pmc_id), file_kv_safe_(std::move(file_kv_safe)) {
|
||||
}
|
||||
|
||||
@ -75,7 +74,7 @@ class FileDb : public FileDbInterface {
|
||||
promise.set_result(load_file_data_impl(actor_id(this), file_pmc(), key));
|
||||
}
|
||||
|
||||
void clear_file_data(Id id, const string &remote_key, const string &local_key, const string &generate_key) {
|
||||
void clear_file_data(FileDbId id, const string &remote_key, const string &local_key, const string &generate_key) {
|
||||
auto &pmc = file_pmc();
|
||||
pmc.begin_transaction().ensure();
|
||||
SCOPE_EXIT {
|
||||
@ -83,12 +82,12 @@ class FileDb : public FileDbInterface {
|
||||
};
|
||||
|
||||
if (id > current_pmc_id_) {
|
||||
pmc.set("file_id", to_string(id));
|
||||
pmc.set("file_id", to_string(id.get()));
|
||||
current_pmc_id_ = id;
|
||||
}
|
||||
|
||||
pmc.erase(PSTRING() << "file" << id);
|
||||
LOG(DEBUG) << "ERASE " << format::as_hex_dump<4>(Slice(PSLICE() << "file" << to_string(id)));
|
||||
pmc.erase(PSTRING() << "file" << id.get());
|
||||
LOG(DEBUG) << "ERASE " << format::as_hex_dump<4>(Slice(PSLICE() << "file" << id.get()));
|
||||
|
||||
if (!remote_key.empty()) {
|
||||
pmc.erase(remote_key);
|
||||
@ -102,7 +101,7 @@ class FileDb : public FileDbInterface {
|
||||
pmc.erase(generate_key);
|
||||
}
|
||||
}
|
||||
void store_file_data(Id id, const string &file_data, const string &remote_key, const string &local_key,
|
||||
void store_file_data(FileDbId id, const string &file_data, const string &remote_key, const string &local_key,
|
||||
const string &generate_key) {
|
||||
auto &pmc = file_pmc();
|
||||
pmc.begin_transaction().ensure();
|
||||
@ -111,23 +110,23 @@ class FileDb : public FileDbInterface {
|
||||
};
|
||||
|
||||
if (id > current_pmc_id_) {
|
||||
pmc.set("file_id", to_string(id));
|
||||
pmc.set("file_id", to_string(id.get()));
|
||||
current_pmc_id_ = id;
|
||||
}
|
||||
|
||||
pmc.set(PSTRING() << "file" << id, file_data);
|
||||
pmc.set(PSTRING() << "file" << id.get(), file_data);
|
||||
|
||||
if (!remote_key.empty()) {
|
||||
pmc.set(remote_key, to_string(id));
|
||||
pmc.set(remote_key, to_string(id.get()));
|
||||
}
|
||||
if (!local_key.empty()) {
|
||||
pmc.set(local_key, to_string(id));
|
||||
pmc.set(local_key, to_string(id.get()));
|
||||
}
|
||||
if (!generate_key.empty()) {
|
||||
pmc.set(generate_key, to_string(id));
|
||||
pmc.set(generate_key, to_string(id.get()));
|
||||
}
|
||||
}
|
||||
void store_file_data_ref(Id id, Id new_id) {
|
||||
void store_file_data_ref(FileDbId id, FileDbId new_id) {
|
||||
auto &pmc = file_pmc();
|
||||
pmc.begin_transaction().ensure();
|
||||
SCOPE_EXIT {
|
||||
@ -135,15 +134,15 @@ class FileDb : public FileDbInterface {
|
||||
};
|
||||
|
||||
if (id > current_pmc_id_) {
|
||||
pmc.set("file_id", to_string(id));
|
||||
pmc.set("file_id", to_string(id.get()));
|
||||
current_pmc_id_ = id;
|
||||
}
|
||||
|
||||
do_store_file_data_ref(id, new_id);
|
||||
}
|
||||
|
||||
void optimize_refs(const std::vector<Id> ids, Id main_id) {
|
||||
LOG(INFO) << "Optimize ids in file database" << format::as_array(ids) << " " << main_id;
|
||||
void optimize_refs(const std::vector<FileDbId> ids, FileDbId main_id) {
|
||||
LOG(INFO) << "Optimize " << ids.size() << " ids in file database to " << main_id.get();
|
||||
auto &pmc = file_pmc();
|
||||
pmc.begin_transaction().ensure();
|
||||
SCOPE_EXIT {
|
||||
@ -155,28 +154,29 @@ class FileDb : public FileDbInterface {
|
||||
}
|
||||
|
||||
private:
|
||||
Id current_pmc_id_;
|
||||
FileDbId current_pmc_id_;
|
||||
std::shared_ptr<SqliteKeyValueSafe> file_kv_safe_;
|
||||
|
||||
SqliteKeyValue &file_pmc() {
|
||||
return file_kv_safe_->get();
|
||||
}
|
||||
|
||||
void do_store_file_data_ref(Id id, Id new_id) {
|
||||
file_pmc().set(PSTRING() << "file" << id, PSTRING() << "@@" << new_id);
|
||||
void do_store_file_data_ref(FileDbId id, FileDbId new_id) {
|
||||
file_pmc().set(PSTRING() << "file" << id.get(), PSTRING() << "@@" << new_id.get());
|
||||
}
|
||||
};
|
||||
|
||||
explicit FileDb(std::shared_ptr<SqliteKeyValueSafe> kv_safe, int scheduler_id = -1) {
|
||||
file_kv_safe_ = std::move(kv_safe);
|
||||
CHECK(file_kv_safe_);
|
||||
current_pmc_id_ = to_integer<int32>(file_kv_safe_->get().get("file_id"));
|
||||
current_pmc_id_ = FileDbId(to_integer<uint64>(file_kv_safe_->get().get("file_id")));
|
||||
file_db_actor_ =
|
||||
create_actor_on_scheduler<FileDbActor>("FileDbActor", scheduler_id, current_pmc_id_, file_kv_safe_);
|
||||
}
|
||||
|
||||
Id create_pmc_id() override {
|
||||
return ++current_pmc_id_;
|
||||
FileDbId create_pmc_id() override {
|
||||
current_pmc_id_ = FileDbId(current_pmc_id_.get() + 1);
|
||||
return current_pmc_id_;
|
||||
}
|
||||
|
||||
void close(Promise<> promise) override {
|
||||
@ -191,7 +191,7 @@ class FileDb : public FileDbInterface {
|
||||
return load_file_data_impl(file_db_actor_.get(), file_kv_safe_->get(), key);
|
||||
}
|
||||
|
||||
void clear_file_data(Id id, const FileData &file_data) override {
|
||||
void clear_file_data(FileDbId id, const FileData &file_data) override {
|
||||
string remote_key;
|
||||
if (file_data.remote_.type() == RemoteFileLocation::Type::Full) {
|
||||
remote_key = as_key(file_data.remote_.full());
|
||||
@ -206,7 +206,8 @@ class FileDb : public FileDbInterface {
|
||||
}
|
||||
send_closure(file_db_actor_, &FileDbActor::clear_file_data, id, remote_key, local_key, generate_key);
|
||||
}
|
||||
void set_file_data(Id id, const FileData &file_data, bool new_remote, bool new_local, bool new_generate) override {
|
||||
void set_file_data(FileDbId id, const FileData &file_data, bool new_remote, bool new_local,
|
||||
bool new_generate) override {
|
||||
string remote_key;
|
||||
if (file_data.remote_.type() == RemoteFileLocation::Type::Full && new_remote) {
|
||||
remote_key = as_key(file_data.remote_.full());
|
||||
@ -219,14 +220,14 @@ class FileDb : public FileDbInterface {
|
||||
if (file_data.generate_ != nullptr && new_generate) {
|
||||
generate_key = as_key(*file_data.generate_);
|
||||
}
|
||||
LOG(DEBUG) << "SAVE " << id << " -> " << file_data << " "
|
||||
LOG(DEBUG) << "SAVE " << id.get() << " -> " << file_data << " "
|
||||
<< tag("remote", format::as_hex_dump<4>(Slice(remote_key)))
|
||||
<< tag("local", format::as_hex_dump<4>(Slice(local_key)));
|
||||
send_closure(file_db_actor_, &FileDbActor::store_file_data, id, serialize(file_data), remote_key, local_key,
|
||||
generate_key);
|
||||
}
|
||||
|
||||
void set_file_data_ref(Id id, Id new_id) override {
|
||||
void set_file_data_ref(FileDbId id, FileDbId new_id) override {
|
||||
send_closure(file_db_actor_, &FileDbActor::store_file_data_ref, id, new_id);
|
||||
}
|
||||
SqliteKeyValue &pmc() override {
|
||||
@ -235,7 +236,7 @@ class FileDb : public FileDbInterface {
|
||||
|
||||
private:
|
||||
ActorOwn<FileDbActor> file_db_actor_;
|
||||
Id current_pmc_id_;
|
||||
FileDbId current_pmc_id_;
|
||||
std::shared_ptr<SqliteKeyValueSafe> file_kv_safe_;
|
||||
|
||||
static Result<FileData> load_file_data_impl(ActorId<FileDbActor> file_db_actor_id, SqliteKeyValue &pmc,
|
||||
@ -243,7 +244,7 @@ class FileDb : public FileDbInterface {
|
||||
//LOG(DEBUG) << "Load by key " << format::as_hex_dump<4>(Slice(key));
|
||||
TRY_RESULT(id, get_id(pmc, key));
|
||||
|
||||
vector<Id> ids;
|
||||
vector<FileDbId> ids;
|
||||
string data_str;
|
||||
int attempt_count = 0;
|
||||
while (true) {
|
||||
@ -252,13 +253,13 @@ class FileDb : public FileDbInterface {
|
||||
}
|
||||
attempt_count++;
|
||||
|
||||
data_str = pmc.get(PSTRING() << "file" << id);
|
||||
data_str = pmc.get(PSTRING() << "file" << id.get());
|
||||
auto data_slice = Slice(data_str);
|
||||
|
||||
if (data_slice.substr(0, 2) == "@@") {
|
||||
ids.push_back(id);
|
||||
|
||||
id = to_integer<Id>(data_slice.substr(2));
|
||||
id = FileDbId(to_integer<uint64>(data_slice.substr(2)));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -266,7 +267,7 @@ class FileDb : public FileDbInterface {
|
||||
if (ids.size() > 1) {
|
||||
send_closure(file_db_actor_id, &FileDbActor::optimize_refs, std::move(ids), id);
|
||||
}
|
||||
//LOG(DEBUG) << "By id " << id << " found data " << format::as_hex_dump<4>(Slice(data_str));
|
||||
//LOG(DEBUG) << "By id " << id.get() << " found data " << format::as_hex_dump<4>(Slice(data_str));
|
||||
//LOG(INFO) << attempt_count;
|
||||
|
||||
FileData data;
|
||||
@ -277,13 +278,13 @@ class FileDb : public FileDbInterface {
|
||||
return std::move(data);
|
||||
}
|
||||
|
||||
static Result<Id> get_id(SqliteKeyValue &pmc, const string &key) TD_WARN_UNUSED_RESULT {
|
||||
static Result<FileDbId> get_id(SqliteKeyValue &pmc, const string &key) TD_WARN_UNUSED_RESULT {
|
||||
auto id_str = pmc.get(key);
|
||||
//LOG(DEBUG) << "Found id " << id_str << " by key " << format::as_hex_dump<4>(Slice(key));
|
||||
if (id_str.empty()) {
|
||||
return Status::Error("There is no such a key in database");
|
||||
}
|
||||
return to_integer<Id>(id_str);
|
||||
return FileDbId(to_integer<uint64>(id_str));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/files/FileDbId.h"
|
||||
#include "td/telegram/files/FileLocation.h"
|
||||
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
@ -16,12 +17,11 @@
|
||||
#include <memory>
|
||||
|
||||
namespace td {
|
||||
|
||||
class SqliteDb;
|
||||
class SqliteConnectionSafe;
|
||||
class SqliteKeyValue;
|
||||
} // namespace td
|
||||
|
||||
namespace td {
|
||||
Status drop_file_db(SqliteDb &db, int32 version) TD_WARN_UNUSED_RESULT;
|
||||
Status init_file_db(SqliteDb &db, int32 version) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
@ -29,18 +29,15 @@ class FileDbInterface;
|
||||
std::shared_ptr<FileDbInterface> create_file_db(std::shared_ptr<SqliteConnectionSafe> connection,
|
||||
int32 scheduler_id = -1) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
using FileDbId = uint64;
|
||||
|
||||
class FileDbInterface {
|
||||
public:
|
||||
using Id = FileDbId;
|
||||
FileDbInterface() = default;
|
||||
FileDbInterface(const FileDbInterface &) = delete;
|
||||
FileDbInterface &operator=(const FileDbInterface &) = delete;
|
||||
virtual ~FileDbInterface() = default;
|
||||
|
||||
// non thread safe
|
||||
virtual Id create_pmc_id() = 0;
|
||||
virtual FileDbId create_pmc_id() = 0;
|
||||
|
||||
// thread safe
|
||||
virtual void close(Promise<> promise) = 0;
|
||||
@ -60,9 +57,10 @@ class FileDbInterface {
|
||||
return res;
|
||||
}
|
||||
|
||||
virtual void clear_file_data(Id id, const FileData &file_data) = 0;
|
||||
virtual void set_file_data(Id id, const FileData &file_data, bool new_remote, bool new_local, bool new_generate) = 0;
|
||||
virtual void set_file_data_ref(Id id, Id new_id) = 0;
|
||||
virtual void clear_file_data(FileDbId id, const FileData &file_data) = 0;
|
||||
virtual void set_file_data(FileDbId id, const FileData &file_data, bool new_remote, bool new_local,
|
||||
bool new_generate) = 0;
|
||||
virtual void set_file_data_ref(FileDbId id, FileDbId new_id) = 0;
|
||||
|
||||
// For FileStatsWorker. TODO: remove it
|
||||
virtual SqliteKeyValue &pmc() = 0;
|
||||
@ -71,5 +69,5 @@ class FileDbInterface {
|
||||
virtual void get_file_data_impl(string key, Promise<FileData> promise) = 0;
|
||||
virtual Result<FileData> get_file_data_sync_impl(string key) = 0;
|
||||
};
|
||||
;
|
||||
|
||||
} // namespace td
|
||||
|
54
td/telegram/files/FileDbId.h
Normal file
54
td/telegram/files/FileDbId.h
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace td {
|
||||
|
||||
class FileDbId {
|
||||
uint64 id = 0;
|
||||
|
||||
public:
|
||||
FileDbId() = default;
|
||||
|
||||
FileDbId(uint64 file_db_id) : id(file_db_id) {
|
||||
}
|
||||
template <class T1, typename = std::enable_if_t<std::is_convertible<T1, uint64>::value>>
|
||||
FileDbId(T1 file_db_id) = delete;
|
||||
|
||||
bool empty() const {
|
||||
return id == 0;
|
||||
}
|
||||
bool is_valid() const {
|
||||
return id > 0;
|
||||
}
|
||||
|
||||
uint64 get() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
bool operator<(const FileDbId &other) const {
|
||||
return id < other.id;
|
||||
}
|
||||
bool operator>(const FileDbId &other) const {
|
||||
return id > other.id;
|
||||
}
|
||||
|
||||
bool operator==(const FileDbId &other) const {
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
bool operator!=(const FileDbId &other) const {
|
||||
return id != other.id;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace td
|
@ -64,4 +64,5 @@ struct FileIdHash {
|
||||
inline StringBuilder &operator<<(StringBuilder &string_builder, FileId file_id) {
|
||||
return string_builder << file_id.get() << "(" << file_id.get_remote() << ")";
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -258,7 +258,7 @@ bool FileNode::need_pmc_flush() const {
|
||||
}
|
||||
|
||||
// already in pmc
|
||||
if (pmc_id_ != 0) {
|
||||
if (pmc_id_.is_valid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -848,7 +848,7 @@ Result<FileId> FileManager::register_file(FileData data, FileLocationSource file
|
||||
data.owner_dialog_id_, std::move(data.encryption_key_), file_id,
|
||||
static_cast<int8>(has_remote));
|
||||
node->remote_source_ = file_location_source;
|
||||
node->pmc_id_ = data.pmc_id_;
|
||||
node->pmc_id_ = FileDbId(data.pmc_id_);
|
||||
get_file_id_info(file_id)->node_id_ = file_node_id;
|
||||
node->file_ids_.push_back(file_id);
|
||||
|
||||
@ -1125,15 +1125,16 @@ Result<FileId> FileManager::merge(FileId x_file_id, FileId y_file_id, bool no_sy
|
||||
}
|
||||
}
|
||||
|
||||
int node_i = std::make_tuple(y_node->pmc_id_ != 0, x_node->pmc_id_, y_node->file_ids_.size(), main_file_id_i == 1) >
|
||||
std::make_tuple(x_node->pmc_id_ != 0, y_node->pmc_id_, x_node->file_ids_.size(), main_file_id_i == 0);
|
||||
int node_i =
|
||||
std::make_tuple(y_node->pmc_id_.is_valid(), x_node->pmc_id_, y_node->file_ids_.size(), main_file_id_i == 1) >
|
||||
std::make_tuple(x_node->pmc_id_.is_valid(), y_node->pmc_id_, x_node->file_ids_.size(), main_file_id_i == 0);
|
||||
|
||||
auto other_node_i = 1 - node_i;
|
||||
FileNodePtr node = nodes[node_i];
|
||||
FileNodePtr other_node = nodes[other_node_i];
|
||||
auto file_view = FileView(node);
|
||||
|
||||
LOG(DEBUG) << "x_node->pmc_id_ = " << x_node->pmc_id_ << ", y_node->pmc_id_ = " << y_node->pmc_id_
|
||||
LOG(DEBUG) << "x_node->pmc_id_ = " << x_node->pmc_id_.get() << ", y_node->pmc_id_ = " << y_node->pmc_id_.get()
|
||||
<< ", x_node_size = " << x_node->file_ids_.size() << ", y_node_size = " << y_node->file_ids_.size()
|
||||
<< ", node_i = " << node_i << ", local_i = " << local_i << ", remote_i = " << remote_i
|
||||
<< ", generate_i = " << generate_i << ", size_i = " << size_i << ", remote_name_i = " << remote_name_i
|
||||
@ -1269,7 +1270,7 @@ Result<FileId> FileManager::merge(FileId x_file_id, FileId y_file_id, bool no_sy
|
||||
run_download(node);
|
||||
run_upload(node, {});
|
||||
|
||||
if (other_pmc_id != 0) {
|
||||
if (other_pmc_id.is_valid()) {
|
||||
// node might not changed, but we need to merge nodes in pmc anyway
|
||||
node->on_pmc_changed();
|
||||
}
|
||||
@ -1284,7 +1285,7 @@ void FileManager::try_flush_node_full(FileNodePtr node, bool new_remote, bool ne
|
||||
if (file_db_) {
|
||||
load_from_pmc(node, true, true, true);
|
||||
flush_to_pmc(node, new_remote, new_local, new_generate);
|
||||
if (other_pmc_id != 0 && node->pmc_id_ != other_pmc_id) {
|
||||
if (other_pmc_id.is_valid() && node->pmc_id_ != other_pmc_id) {
|
||||
file_db_->set_file_data_ref(other_pmc_id, node->pmc_id_);
|
||||
}
|
||||
}
|
||||
@ -1323,7 +1324,7 @@ void FileManager::clear_from_pmc(FileNodePtr node) {
|
||||
if (!file_db_) {
|
||||
return;
|
||||
}
|
||||
if (node->pmc_id_ == 0) {
|
||||
if (node->pmc_id_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1340,7 +1341,7 @@ void FileManager::clear_from_pmc(FileNodePtr node) {
|
||||
data.generate_ = make_unique<FullGenerateFileLocation>(*node->generate_);
|
||||
}
|
||||
file_db_->clear_file_data(node->pmc_id_, data);
|
||||
node->pmc_id_ = 0;
|
||||
node->pmc_id_ = FileDbId();
|
||||
}
|
||||
|
||||
void FileManager::flush_to_pmc(FileNodePtr node, bool new_remote, bool new_local, bool new_generate) {
|
||||
@ -1349,13 +1350,13 @@ void FileManager::flush_to_pmc(FileNodePtr node, bool new_remote, bool new_local
|
||||
}
|
||||
FileView view(node);
|
||||
bool create_flag = false;
|
||||
if (node->pmc_id_ == 0) {
|
||||
if (node->pmc_id_.empty()) {
|
||||
create_flag = true;
|
||||
node->pmc_id_ = file_db_->create_pmc_id();
|
||||
}
|
||||
|
||||
FileData data;
|
||||
data.pmc_id_ = node->pmc_id_;
|
||||
data.pmc_id_ = node->pmc_id_.get();
|
||||
data.local_ = node->local_;
|
||||
if (data.local_.type() == LocalFileLocation::Type::Full) {
|
||||
prepare_path_for_pmc(data.local_.full().file_type_, data.local_.full().path_);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/files/FileDb.h"
|
||||
#include "td/telegram/files/FileDbId.h"
|
||||
#include "td/telegram/files/FileEncryptionKey.h"
|
||||
#include "td/telegram/files/FileGenerateManager.h"
|
||||
#include "td/telegram/files/FileId.h"
|
||||
@ -112,7 +113,7 @@ class FileNode {
|
||||
string url_;
|
||||
DialogId owner_dialog_id_;
|
||||
FileEncryptionKey encryption_key_;
|
||||
FileDbId pmc_id_ = 0;
|
||||
FileDbId pmc_id_;
|
||||
std::vector<FileId> file_ids_;
|
||||
|
||||
FileId main_file_id_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user