• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 #ifndef ICING_STORE_USAGE_STORE_H_
22 #define ICING_STORE_USAGE_STORE_H_
23 
24 namespace icing {
25 namespace lib {
26 
27 // A storage class that maintains scores that are calculated based on usage
28 // reports.
29 class UsageStore {
30  public:
31   // Factory function to create a UsageStore instance. The base directory is
32   // used to persist usage scores. If a usage store was previously created with
33   // this directory, it will reload the files saved by the last instance.
34   //
35   // TODO(b/169594617): consider returning StatusOr<UsageStore>
36   //
37   // Returns:
38   //   A UsageStore on success
39   //   FAILED_PRECONDITION on any null pointer input
40   //   INTERNAL_ERROR on I/O error
41   static libtextclassifier3::StatusOr<std::unique_ptr<UsageStore>> Create(
42       const Filesystem* filesystem, const std::string& base_dir);
43 
44   // The scores here reflect the timestamps and usage types defined in
45   // usage.proto.
46   struct UsageScores {
47     // The latest timestamp in seconds reported with custom usage type 1.
48     uint32_t usage_type1_last_used_timestamp_s = 0;
49 
50     // The latest timestamp in seconds reported with custom usage type 2.
51     uint32_t usage_type2_last_used_timestamp_s = 0;
52 
53     // The latest timestamp in seconds reported with custom usage type 3.
54     uint32_t usage_type3_last_used_timestamp_s = 0;
55 
56     // Count of reports with custom usage type 1
57     int usage_type1_count = 0;
58 
59     // Count of reports with custom usage type 2
60     int usage_type2_count = 0;
61 
62     // Count of reports with custom usage type 3
63     int usage_type3_count = 0;
64 
65     bool operator==(const UsageScores& other) const {
66       return usage_type1_last_used_timestamp_s ==
67                  other.usage_type1_last_used_timestamp_s &&
68              usage_type2_last_used_timestamp_s ==
69                  other.usage_type2_last_used_timestamp_s &&
70              usage_type3_last_used_timestamp_s ==
71                  other.usage_type3_last_used_timestamp_s &&
72              usage_type1_count == other.usage_type1_count &&
73              usage_type2_count == other.usage_type2_count &&
74              usage_type3_count == other.usage_type3_count;
75     }
76   };
77 
78   // Adds one usage report. The corresponding usage scores of the specified
79   // document will be updated.
80   //
81   // Note: changes are written to disk automatically, callers can also call
82   // PersistToDisk() to flush changes immediately.
83   //
84   // Returns:
85   //   OK on success
86   //   INVALID_ARGUMENT if document_id is invalid
87   //   INTERNAL_ERROR on I/O errors.
88   libtextclassifier3::Status AddUsageReport(const UsageReport& report,
89                                             DocumentId document_id);
90 
91   // Deletes the usage scores of a document.
92   //
93   // Note: changes are written to disk automatically, callers can also call
94   // PersistToDisk() to flush changes immediately.
95   //
96   // Returns:
97   //   OK on success
98   //   INVALID_ARGUMENT if document_id is invalid
99   //   INTERNAL_ERROR on I/O errors
100   libtextclassifier3::Status DeleteUsageScores(DocumentId document_id);
101 
102   // Gets the usage scores of a document.
103   //
104   // Returns:
105   //   UsageScores on success
106   //   INVALID_ARGUMENT if document_id is invalid
107   //   INTERNAL_ERROR on I/O errors
108   //
109   // TODO(b/169433395): return a pointer instead of an object.
110   libtextclassifier3::StatusOr<UsageScores> GetUsageScores(
111       DocumentId document_id);
112 
113   // Sets the usage scores of a document.
114   //
115   // Note: changes are written to disk automatically, callers can also call
116   // PersistToDisk() to flush changes immediately.
117   //
118   // Returns:
119   //   OK on success
120   //   INVALID_ARGUMENT if document_id is invalid
121   //   INTERNAL_ERROR on I/O errors
122   libtextclassifier3::Status SetUsageScores(DocumentId document_id,
123                                             const UsageScores& usage_scores);
124 
125   // Clones the usage scores from one document to another.
126   //
127   // Returns:
128   //   OK on success
129   //   INVALID_ARGUMENT if any of the document ids is invalid
130   //   INTERNAL_ERROR on I/O errors
131   //
132   // TODO(b/169433395): We can remove this method once GetUsageScores() returns
133   // a pointer.
134   libtextclassifier3::Status CloneUsageScores(DocumentId from_document_id,
135                                               DocumentId to_document_id);
136 
137   // Syncs data to disk.
138   //
139   // Returns:
140   //   OK on success
141   //   INTERNAL on I/O error
142   libtextclassifier3::Status PersistToDisk();
143 
144   // Updates checksum of the usage scores and returns it.
145   //
146   // Returns:
147   //   A Crc32 on success
148   //   INTERNAL_ERROR if the internal state is inconsistent
149   libtextclassifier3::StatusOr<Crc32> ComputeChecksum();
150 
151   // Returns the file size of the all the elements held in the UsageStore. File
152   // size is in bytes. This excludes the size of any internal metadata, e.g. any
153   // internal headers.
154   //
155   // Returns:
156   //   File size on success
157   //   INTERNAL_ERROR on IO error
158   libtextclassifier3::StatusOr<int64_t> GetElementsFileSize() const;
159 
160   // Calculates and returns the disk usage in bytes. Rounds up to the nearest
161   // block size.
162   //
163   // Returns:
164   //   Disk usage on success
165   //   INTERNAL_ERROR on IO error
166   libtextclassifier3::StatusOr<int64_t> GetDiskUsage() const;
167 
168   // Resizes the storage so that only the usage scores of and before
169   // last_document_id are stored.
170   //
171   // Returns:
172   //   OK on success
173   //   OUT_OF_RANGE_ERROR if num_documents is negative
174   libtextclassifier3::Status TruncateTo(DocumentId num_documents);
175 
176   // Deletes all usage data and re-initialize the storage.
177   //
178   // Returns:
179   //   OK on success
180   //   INTERNAL_ERROR on I/O error
181   libtextclassifier3::Status Reset();
182 
num_elements()183   int32_t num_elements() const { return usage_score_cache_->num_elements(); }
184 
185  private:
UsageStore(std::unique_ptr<FileBackedVector<UsageScores>> document_id_to_scores_mapper,const Filesystem & filesystem,std::string base_dir)186   explicit UsageStore(std::unique_ptr<FileBackedVector<UsageScores>>
187                           document_id_to_scores_mapper,
188                       const Filesystem& filesystem, std::string base_dir)
189       : filesystem_(filesystem),
190         base_dir_(std::move(base_dir)),
191         usage_score_cache_(std::move(document_id_to_scores_mapper)) {}
192 
193   const Filesystem& filesystem_;
194 
195   // Base directory where the files are located.
196   const std::string base_dir_;
197 
198   // Used to store the usage scores of documents.
199   std::unique_ptr<FileBackedVector<UsageScores>> usage_score_cache_;
200 };
201 
202 }  // namespace lib
203 }  // namespace icing
204 
205 #endif  // ICING_STORE_USAGE_STORE_H_
206