experimental td_api::getDatabaseStatistics

GitOrigin-RevId: ed4e39caef210a14e1c72f0660690ffd7e974aff
This commit is contained in:
Arseny Smirnov 2019-04-17 12:17:51 +03:00
parent c1eadfdc14
commit c1d94fc821
9 changed files with 90 additions and 0 deletions

View File

@ -2262,6 +2262,9 @@ storageStatistics size:int53 count:int32 by_chat:vector<storageStatisticsByChat>
//@description Contains approximate storage usage statistics, excluding files of unknown file type @files_size Approximate total size of files @file_count Approximate number of files @database_size Size of the database
storageStatisticsFast files_size:int53 file_count:int32 database_size:int53 = StorageStatisticsFast;
//@description Experimental database statistics
//@debug Database statistics in an unspecified format
databaseStatistics debug:string = DatabaseStatistics;
//@class NetworkType @description Represents the type of a network
@ -3613,6 +3616,9 @@ getStorageStatistics chat_limit:int32 = StorageStatistics;
//@description Quickly returns approximate storage usage statistics. Can be called before authorization
getStorageStatisticsFast = StorageStatisticsFast;
//@description Returns DatabaseStatistics
getDatabaseStatistics = DatabaseStatistics;
//@description Optimizes storage usage, i.e. deletes some files and returns new storage usage statistics. Secret thumbnails can't be deleted
//@size Limit on the total size of files after deletion. Pass -1 to use the default limit
//@ttl Limit on the time that has passed since the last time a file was accessed (or creation time for some filesystems). Pass -1 to use the default limit

Binary file not shown.

View File

@ -15,6 +15,8 @@
#include "td/telegram/MessagesManager.h"
#include "td/telegram/TdDb.h"
#include "td/telegram/td_api.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/port/Clocks.h"
@ -25,6 +27,10 @@
namespace td {
tl_object_ptr<td_api::databaseStatistics> DatabaseStats::as_td_api() const {
return make_tl_object<td_api::databaseStatistics>(debug);
}
StorageManager::StorageManager(ActorShared<> parent, int32 scheduler_id)
: parent_(std::move(parent)), scheduler_id_(scheduler_id) {
}
@ -67,6 +73,16 @@ void StorageManager::get_storage_stats_fast(Promise<FileStatsFast> promise) {
promise.set_value(FileStatsFast(fast_stat_.size, fast_stat_.cnt, get_db_size()));
}
void StorageManager::get_database_stats(Promise<DatabaseStats> promise) {
//TODO: use another thread
auto r_stats = G()->td_db()->get_stats();
if (r_stats.is_error()) {
promise.set_error(r_stats.move_as_error());
} else {
promise.set_value(DatabaseStats(r_stats.move_as_ok()));
}
}
void StorageManager::update_use_storage_optimizer() {
schedule_next_gc();
}

View File

@ -17,12 +17,24 @@
#include "td/utils/Status.h"
namespace td {
namespace td_api {
class databaseStatistics;
} // namespace td_api
struct DatabaseStats {
string debug;
DatabaseStats() = default;
explicit DatabaseStats(string debug) : debug(debug) {
}
tl_object_ptr<td_api::databaseStatistics> as_td_api() const;
};
class StorageManager : public Actor {
public:
StorageManager(ActorShared<> parent, int32 scheduler_id);
void get_storage_stats(int32 dialog_limit, Promise<FileStats> promise);
void get_storage_stats_fast(Promise<FileStatsFast> promise);
void get_database_stats(Promise<DatabaseStats> promise);
void run_gc(FileGcParameters parameters, Promise<FileStats> promise);
void update_use_storage_optimizer();

View File

@ -3212,6 +3212,7 @@ bool Td::is_preauthentication_request(int32 id) {
case td_api::setOption::ID:
case td_api::getStorageStatistics::ID:
case td_api::getStorageStatisticsFast::ID:
case td_api::getDatabaseStatistics::ID:
case td_api::setNetworkType::ID:
case td_api::getNetworkStatistics::ID:
case td_api::addNetworkStatistics::ID:
@ -4990,6 +4991,17 @@ void Td::on_request(uint64 id, td_api::getStorageStatisticsFast &request) {
});
send_closure(storage_manager_, &StorageManager::get_storage_stats_fast, std::move(query_promise));
}
void Td::on_request(uint64 id, td_api::getDatabaseStatistics &request) {
CREATE_REQUEST_PROMISE();
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<DatabaseStats> result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(result.ok().as_td_api());
}
});
send_closure(storage_manager_, &StorageManager::get_database_stats, std::move(query_promise));
}
void Td::on_request(uint64 id, td_api::optimizeStorage &request) {
std::vector<FileType> file_types;

View File

@ -481,6 +481,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::getStorageStatisticsFast &request);
void on_request(uint64 id, td_api::getDatabaseStatistics &request);
void on_request(uint64 id, td_api::optimizeStorage &request);
void on_request(uint64 id, td_api::getNetworkStatistics &request);

View File

@ -481,4 +481,42 @@ void TdDb::with_db_path(std::function<void(CSlice)> callback) {
callback(binlog_path());
}
Result<string> TdDb::get_stats() {
auto sb = td::StringBuilder({}, true);
auto &sql = sql_connection_->get();
auto run_query = [&](CSlice query, Slice desc) -> Status {
TRY_RESULT(stmt, sql.get_statement(query));
TRY_STATUS(stmt.step());
CHECK(stmt.has_row());
auto key_size = stmt.view_int64(0);
auto value_size = stmt.view_int64(1);
auto count = stmt.view_int64(2);
sb << query << "\n";
sb << desc << ":\n";
sb << format::as_size(key_size + value_size) << "\t";
sb << format::as_size(key_size) << "\t";
sb << format::as_size(value_size) << "\t";
sb << format::as_size((key_size + value_size) / (count ? count : 1)) << "\t";
sb << "\n";
return Status::OK();
};
auto run_kv_query = [&](Slice mask, Slice table = "common") {
return run_query(PSLICE() << "SELECT SUM(length(k)), SUM(length(v)), COUNT(*) FROM " << table << " WHERE k like '"
<< mask << "'",
PSLICE() << table << ":" << mask);
};
TRY_STATUS(run_query("SELECT 0, SUM(length(data)), COUNT(*) FROM messages WHERE 1", "messages"));
TRY_STATUS(run_query("SELECT 0, SUM(length(data)), COUNT(*) FROM dialogs WHERE 1", "dialogs"));
TRY_STATUS(run_kv_query("%", "common"));
TRY_STATUS(run_kv_query("%", "files"));
TRY_STATUS(run_kv_query("%wp"));
TRY_STATUS(run_kv_query("wpurl%"));
TRY_STATUS(run_kv_query("wpiv%"));
TRY_STATUS(run_kv_query("us%"));
TRY_STATUS(run_kv_query("ch%"));
TRY_STATUS(run_kv_query("ss%"));
TRY_STATUS(run_kv_query("gr%"));
return sb.as_cslice().str();
}
} // namespace td

View File

@ -99,6 +99,8 @@ class TdDb {
void with_db_path(std::function<void(CSlice)> callback);
Result<string> get_stats();
private:
string sqlite_path_;
std::shared_ptr<SqliteConnectionSafe> sql_connection_;

View File

@ -2023,6 +2023,8 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::getStorageStatistics>(chat_limit));
} else if (op == "storage_fast") {
send_request(td_api::make_object<td_api::getStorageStatisticsFast>());
} else if (op == "database") {
send_request(td_api::make_object<td_api::getDatabaseStatistics>());
} else if (op == "optimize_storage") {
string chat_ids;
string exclude_chat_ids;