1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef FCP_CLIENT_OPSTATS_PDS_BACKED_OPSTATS_DB_H_ 17 #define FCP_CLIENT_OPSTATS_PDS_BACKED_OPSTATS_DB_H_ 18 19 #include <functional> 20 #include <string> 21 #include <utility> 22 23 #include "absl/container/flat_hash_set.h" 24 #include "absl/status/status.h" 25 #include "absl/status/statusor.h" 26 #include "fcp/client/log_manager.h" 27 #include "fcp/client/opstats/opstats_db.h" 28 #include "fcp/protos/opstats.pb.h" 29 #include "protostore/file-storage.h" 30 #include "protostore/proto-data-store.h" 31 32 namespace fcp { 33 namespace client { 34 namespace opstats { 35 36 // An implementation of OpStatsDb based on protodatastore cpp. 37 class PdsBackedOpStatsDb : public OpStatsDb { 38 public: 39 static constexpr char kParentDir[] = "fcp/opstats"; 40 static constexpr char kDbFileName[] = "opstats.pb"; 41 42 // Factory method to create PdsBackedOpStatsDb. The provided path is the 43 // absolute path for the base directory for storing files. OpStatsDb will 44 // attempt to create subdirectories and file, so the directory must grant 45 // read/write access. The ttl is the duration that an OperationalStats message 46 // is kept since its last update time. 47 static absl::StatusOr<std::unique_ptr<OpStatsDb>> Create( 48 const std::string& base_dir, absl::Duration ttl, LogManager& log_manager, 49 int64_t max_size_bytes); 50 51 ~PdsBackedOpStatsDb() override; 52 53 // Returns the data in the db, or an error from the read operation. If the 54 // read fails, will try to reset the db to be empty. The returned data is not 55 // necessarily restricted according to the ttl. 56 absl::StatusOr<OpStatsSequence> Read() override ABSL_LOCKS_EXCLUDED(mutex_); 57 58 // Modifies the data in the db based on the supplied transformation function 59 // and ttl restrictions. If there is an error fetching the existing data, the 60 // db is reset. No transformation is applied if the reset fails. 61 absl::Status Transform(std::function<void(OpStatsSequence&)> func) override 62 ABSL_LOCKS_EXCLUDED(mutex_); 63 64 private: PdsBackedOpStatsDb(std::unique_ptr<protostore::ProtoDataStore<OpStatsSequence>> db,std::unique_ptr<protostore::FileStorage> file_storage,absl::Duration ttl,LogManager & log_manager,int64_t max_size_bytes,std::function<void ()> lock_releaser)65 PdsBackedOpStatsDb( 66 std::unique_ptr<protostore::ProtoDataStore<OpStatsSequence>> db, 67 std::unique_ptr<protostore::FileStorage> file_storage, absl::Duration ttl, 68 LogManager& log_manager, int64_t max_size_bytes, 69 std::function<void()> lock_releaser) 70 : ttl_(std::move(ttl)), 71 db_(std::move(db)), 72 storage_(std::move(file_storage)), 73 log_manager_(log_manager), 74 max_size_bytes_(max_size_bytes), 75 lock_releaser_(lock_releaser) {} 76 77 const absl::Duration ttl_; 78 std::unique_ptr<protostore::ProtoDataStore<OpStatsSequence>> db_ 79 ABSL_GUARDED_BY(mutex_); 80 std::unique_ptr<protostore::FileStorage> storage_; 81 LogManager& log_manager_; 82 const int64_t max_size_bytes_; 83 std::function<void()> lock_releaser_; 84 absl::Mutex mutex_; 85 }; 86 87 } // namespace opstats 88 } // namespace client 89 } // namespace fcp 90 91 #endif // FCP_CLIENT_OPSTATS_PDS_BACKED_OPSTATS_DB_H_ 92