1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/telegram/files/FileGcWorker.h"
10 #include "td/telegram/files/FileStats.h"
11 #include "td/telegram/files/FileStatsWorker.h"
12 #include "td/telegram/td_api.h"
13 
14 #include "td/actor/actor.h"
15 #include "td/actor/PromiseFuture.h"
16 
17 #include "td/utils/CancellationToken.h"
18 #include "td/utils/common.h"
19 #include "td/utils/Slice.h"
20 #include "td/utils/Status.h"
21 
22 namespace td {
23 
24 struct DatabaseStats {
25   string debug;
26   DatabaseStats() = default;
DatabaseStatsDatabaseStats27   explicit DatabaseStats(string debug) : debug(std::move(debug)) {
28   }
29   tl_object_ptr<td_api::databaseStatistics> get_database_statistics_object() const;
30 };
31 
32 class StorageManager final : public Actor {
33  public:
34   StorageManager(ActorShared<> parent, int32 scheduler_id);
35   void get_storage_stats(bool need_all_files, int32 dialog_limit, Promise<FileStats> promise);
36   void get_storage_stats_fast(Promise<FileStatsFast> promise);
37   void get_database_stats(Promise<DatabaseStats> promise);
38   void run_gc(FileGcParameters parameters, bool return_deleted_file_statistics, Promise<FileStats> promise);
39   void update_use_storage_optimizer();
40 
41   void on_new_file(int64 size, int64 real_size, int32 cnt);
42 
43  private:
44   static constexpr int GC_EACH = 60 * 60 * 24;  // 1 day
45   static constexpr int GC_DELAY = 60;
46   static constexpr int GC_RAND_DELAY = 60 * 15;
47 
48   ActorShared<> parent_;
49 
50   int32 scheduler_id_;
51 
52   // get stats
53   ActorOwn<FileStatsWorker> stats_worker_;
54   std::vector<Promise<FileStats>> pending_storage_stats_;
55   uint32 stats_generation_{0};
56   int32 stats_dialog_limit_{0};
57   bool stats_need_all_files_{false};
58 
59   FileTypeStat fast_stat_;
60 
61   CancellationTokenSource stats_cancellation_token_source_;
62   CancellationTokenSource gc_cancellation_token_source_;
63 
64   void on_file_stats(Result<FileStats> r_file_stats, uint32 generation);
65   void create_stats_worker();
66   void update_fast_stats(const FileStats &stats);
67   static void send_stats(FileStats &&stats, int32 dialog_limit, std::vector<Promise<FileStats>> &&promises);
68 
69   void save_fast_stat();
70   void load_fast_stat();
71   static int64 get_database_size();
72   static int64 get_language_pack_database_size();
73   static int64 get_log_size();
74   static int64 get_file_size(CSlice path);
75 
76   // RefCnt
77   int32 ref_cnt_{1};
78   bool is_closed_{false};
79   ActorShared<> create_reference();
80   void start_up() final;
81   void hangup_shared() final;
82   void hangup() final;
83 
84   // Gc
85   ActorOwn<FileGcWorker> gc_worker_;
86   std::vector<Promise<FileStats>> pending_run_gc_[2];
87 
88   uint32 last_gc_timestamp_ = 0;
89   double next_gc_at_ = 0;
90 
91   void on_all_files(FileGcParameters gc_parameters, Result<FileStats> r_file_stats);
92   void create_gc_worker();
93   void on_gc_finished(int32 dialog_limit, Result<FileGcResult> r_file_gc_result);
94 
95   void close_stats_worker();
96   void close_gc_worker();
97 
98   uint32 load_last_gc_timestamp();
99   void save_last_gc_timestamp();
100   void schedule_next_gc();
101 
102   void timeout_expired() final;
103 };
104 
105 }  // namespace td
106