xref: /aosp_15_r20/external/icing/icing/store/usage-store.h (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <cstdint>
16 
17 #include "icing/file/file-backed-vector.h"
18 #include "icing/proto/usage.pb.h"
19 #include "icing/store/document-id.h"
20 #include "icing/util/crc32.h"
21 
22 #ifndef ICING_STORE_USAGE_STORE_H_
23 #define ICING_STORE_USAGE_STORE_H_
24 
25 namespace icing {
26 namespace lib {
27 
28 // A storage class that maintains scores that are calculated based on usage
29 // reports.
30 class UsageStore {
31  public:
32   // Factory function to create a UsageStore instance. The base directory is
33   // used to persist usage scores. If a usage store was previously created with
34   // this directory, it will reload the files saved by the last instance.
35   //
36   // TODO(b/169594617): consider returning StatusOr<UsageStore>
37   //
38   // Returns:
39   //   A UsageStore on success
40   //   FAILED_PRECONDITION on any null pointer input
41   //   INTERNAL_ERROR on I/O error
42   static libtextclassifier3::StatusOr<std::unique_ptr<UsageStore>> Create(
43       const Filesystem* filesystem, const std::string& base_dir);
44 
45   // The scores here reflect the timestamps and usage types defined in
46   // usage.proto.
47   struct UsageScores {
48     // The latest timestamp in seconds reported with custom usage type 1.
49     uint32_t usage_type1_last_used_timestamp_s = 0;
50 
51     // The latest timestamp in seconds reported with custom usage type 2.
52     uint32_t usage_type2_last_used_timestamp_s = 0;
53 
54     // The latest timestamp in seconds reported with custom usage type 3.
55     uint32_t usage_type3_last_used_timestamp_s = 0;
56 
57     // Count of reports with custom usage type 1
58     int usage_type1_count = 0;
59 
60     // Count of reports with custom usage type 2
61     int usage_type2_count = 0;
62 
63     // Count of reports with custom usage type 3
64     int usage_type3_count = 0;
65 
66     bool operator==(const UsageScores& other) const {
67       return usage_type1_last_used_timestamp_s ==
68                  other.usage_type1_last_used_timestamp_s &&
69              usage_type2_last_used_timestamp_s ==
70                  other.usage_type2_last_used_timestamp_s &&
71              usage_type3_last_used_timestamp_s ==
72                  other.usage_type3_last_used_timestamp_s &&
73              usage_type1_count == other.usage_type1_count &&
74              usage_type2_count == other.usage_type2_count &&
75              usage_type3_count == other.usage_type3_count;
76     }
77   };
78 
79   // Adds one usage report. The corresponding usage scores of the specified
80   // document will be updated.
81   //
82   // Note: changes are written to disk automatically, callers can also call
83   // PersistToDisk() to flush changes immediately.
84   //
85   // Returns:
86   //   OK on success
87   //   INVALID_ARGUMENT if document_id is invalid
88   //   INTERNAL_ERROR on I/O errors.
89   libtextclassifier3::Status AddUsageReport(const UsageReport& report,
90                                             DocumentId document_id);
91 
92   // Deletes the usage scores of a document.
93   //
94   // Note: changes are written to disk automatically, callers can also call
95   // PersistToDisk() to flush changes immediately.
96   //
97   // Returns:
98   //   OK on success
99   //   INVALID_ARGUMENT if document_id is invalid
100   //   INTERNAL_ERROR on I/O errors
101   libtextclassifier3::Status DeleteUsageScores(DocumentId document_id);
102 
103   // Gets the usage scores of a document.
104   //
105   // Returns:
106   //   UsageScores on success
107   //   INVALID_ARGUMENT if document_id is invalid
108   //   INTERNAL_ERROR on I/O errors
109   //
110   // TODO(b/169433395): return a pointer instead of an object.
111   libtextclassifier3::StatusOr<UsageScores> GetUsageScores(
112       DocumentId document_id);
113 
114   // Sets the usage scores of a document.
115   //
116   // Note: changes are written to disk automatically, callers can also call
117   // PersistToDisk() to flush changes immediately.
118   //
119   // Returns:
120   //   OK on success
121   //   INVALID_ARGUMENT if document_id is invalid
122   //   INTERNAL_ERROR on I/O errors
123   libtextclassifier3::Status SetUsageScores(DocumentId document_id,
124                                             const UsageScores& usage_scores);
125 
126   // Clones the usage scores from one document to another.
127   //
128   // Returns:
129   //   OK on success
130   //   INVALID_ARGUMENT if any of the document ids is invalid
131   //   INTERNAL_ERROR on I/O errors
132   //
133   // TODO(b/169433395): We can remove this method once GetUsageScores() returns
134   // a pointer.
135   libtextclassifier3::Status CloneUsageScores(DocumentId from_document_id,
136                                               DocumentId to_document_id);
137 
138   // Syncs data to disk.
139   //
140   // Returns:
141   //   OK on success
142   //   INTERNAL on I/O error
143   libtextclassifier3::Status PersistToDisk();
144 
145   // Updates checksum of the usage scores and saves it in the header.
146   //
147   // Returns:
148   //   A Crc32 on success
149   //   INTERNAL_ERROR if the internal state is inconsistent
150   libtextclassifier3::StatusOr<Crc32> UpdateChecksum();
151 
152   // Calculates the checksum of the usage scores and returns it. Does NOT update
153   // the checksum in the header.
154   Crc32 GetChecksum() const;
155 
156   // Returns the file size of the all the elements held in the UsageStore. File
157   // size is in bytes. This excludes the size of any internal metadata, e.g. any
158   // internal headers.
159   //
160   // Returns:
161   //   File size on success
162   //   INTERNAL_ERROR on IO error
163   libtextclassifier3::StatusOr<int64_t> GetElementsFileSize() const;
164 
165   // Calculates and returns the disk usage in bytes. Rounds up to the nearest
166   // block size.
167   //
168   // Returns:
169   //   Disk usage on success
170   //   INTERNAL_ERROR on IO error
171   libtextclassifier3::StatusOr<int64_t> GetDiskUsage() const;
172 
173   // Resizes the storage so that only the usage scores of and before
174   // last_document_id are stored.
175   //
176   // Returns:
177   //   OK on success
178   //   OUT_OF_RANGE_ERROR if num_documents is negative
179   libtextclassifier3::Status TruncateTo(DocumentId num_documents);
180 
181   // Deletes all usage data and re-initialize the storage.
182   //
183   // Returns:
184   //   OK on success
185   //   INTERNAL_ERROR on I/O error
186   libtextclassifier3::Status Reset();
187 
num_elements()188   int32_t num_elements() const { return usage_score_cache_->num_elements(); }
189 
190  private:
UsageStore(std::unique_ptr<FileBackedVector<UsageScores>> document_id_to_scores_mapper,const Filesystem & filesystem,std::string base_dir)191   explicit UsageStore(std::unique_ptr<FileBackedVector<UsageScores>>
192                           document_id_to_scores_mapper,
193                       const Filesystem& filesystem, std::string base_dir)
194       : filesystem_(filesystem),
195         base_dir_(std::move(base_dir)),
196         usage_score_cache_(std::move(document_id_to_scores_mapper)) {}
197 
198   const Filesystem& filesystem_;
199 
200   // Base directory where the files are located.
201   const std::string base_dir_;
202 
203   // Used to store the usage scores of documents.
204   std::unique_ptr<FileBackedVector<UsageScores>> usage_score_cache_;
205 };
206 
207 }  // namespace lib
208 }  // namespace icing
209 
210 #endif  // ICING_STORE_USAGE_STORE_H_
211