1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_LEVELDB_SITE_DATA_STORE_H_
6 #define COMPONENTS_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_LEVELDB_SITE_DATA_STORE_H_
7 
8 #include "base/auto_reset.h"
9 #include "base/files/file_path.h"
10 #include "base/macros.h"
11 #include "base/sequence_checker.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/task/post_task.h"
14 #include "components/performance_manager/persistence/site_data/site_data_store.h"
15 #include "third_party/leveldatabase/src/include/leveldb/db.h"
16 
17 namespace performance_manager {
18 
19 // Manages a LevelDB database used by a site data store.
20 // TODO(sebmarchand):
21 //   - Constrain the size of the database: Use a background task to trim the
22 //     database if it becomes too big and ensure that this fails nicely when the
23 //     disk is full.
24 //   - Batch the write operations to reduce the number of I/O events.
25 //
26 // All the DB operations are done asynchronously on a sequence allowed to do
27 // I/O operations.
28 class LevelDBSiteDataStore : public SiteDataStore {
29  public:
30   explicit LevelDBSiteDataStore(const base::FilePath& db_path);
31 
32   ~LevelDBSiteDataStore() override;
33 
34   // SiteDataStore:
35   void ReadSiteDataFromStore(
36       const url::Origin& origin,
37       SiteDataStore::ReadSiteDataFromStoreCallback callback) override;
38   void WriteSiteDataIntoStore(
39       const url::Origin& origin,
40       const SiteDataProto& site_characteristic_proto) override;
41   void RemoveSiteDataFromStore(
42       const std::vector<url::Origin>& site_origins) override;
43   void ClearStore() override;
44   void GetStoreSize(GetStoreSizeCallback callback) override;
45   void SetInitializationCallbackForTesting(base::OnceClosure callback) override;
46 
47   bool DatabaseIsInitializedForTesting();
48 
49   // Returns a raw pointer to the database for testing purposes. Note that as
50   // the DB operations are made on a separate sequence it's recommended to call
51   // TaskEnvironment::RunUntilIdle before calling this function to ensure
52   // that the database has been fully initialized. The LevelDB implementation is
53   // thread safe.
54   leveldb::DB* GetDBForTesting();
55 
56   // Make the new instances of this class use an in memory database rather than
57   // creating it on disk.
58   static std::unique_ptr<base::AutoReset<bool>> UseInMemoryDBForTesting();
59 
60   static const size_t kDbVersion;
61   static const char kDbMetadataKey[];
62 
63  private:
64   class AsyncHelper;
65 
66   // The task runner used to run all the blocking operations.
67   const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
68 
69   // Helper object that should be used to trigger all the operations that need
70   // to run on |blocking_task_runner_|, it is guaranteed that the AsyncHelper
71   // held by this object will only be destructed once all the tasks that have
72   // been posted to it have completed.
73   std::unique_ptr<AsyncHelper, base::OnTaskRunnerDeleter> async_helper_;
74 
75   SEQUENCE_CHECKER(sequence_checker_);
76 
77   DISALLOW_COPY_AND_ASSIGN(LevelDBSiteDataStore);
78 };
79 
80 }  // namespace performance_manager
81 
82 #endif  // COMPONENTS_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_LEVELDB_SITE_DATA_STORE_H_
83