Home | History | Annotate | Download | only in simple
      1 // Copyright (c) 2013 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 NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
      6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
      7 
      8 #include <list>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/callback.h"
     13 #include "base/containers/hash_tables.h"
     14 #include "base/files/file_path.h"
     15 #include "base/gtest_prod_util.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/memory/scoped_ptr.h"
     18 #include "base/memory/weak_ptr.h"
     19 #include "base/single_thread_task_runner.h"
     20 #include "base/threading/thread_checker.h"
     21 #include "base/time/time.h"
     22 #include "base/timer/timer.h"
     23 #include "net/base/cache_type.h"
     24 #include "net/base/completion_callback.h"
     25 #include "net/base/net_export.h"
     26 
     27 #if defined(OS_ANDROID)
     28 #include "base/android/application_status_listener.h"
     29 #endif
     30 
     31 class Pickle;
     32 class PickleIterator;
     33 
     34 namespace disk_cache {
     35 
     36 class SimpleIndexDelegate;
     37 class SimpleIndexFile;
     38 struct SimpleIndexLoadResult;
     39 
     40 class NET_EXPORT_PRIVATE EntryMetadata {
     41  public:
     42   EntryMetadata();
     43   EntryMetadata(base::Time last_used_time, int entry_size);
     44 
     45   base::Time GetLastUsedTime() const;
     46   void SetLastUsedTime(const base::Time& last_used_time);
     47 
     48   int GetEntrySize() const { return entry_size_; }
     49   void SetEntrySize(int entry_size) { entry_size_ = entry_size; }
     50 
     51   // Serialize the data into the provided pickle.
     52   void Serialize(Pickle* pickle) const;
     53   bool Deserialize(PickleIterator* it);
     54 
     55   static base::TimeDelta GetLowerEpsilonForTimeComparisons() {
     56     return base::TimeDelta::FromSeconds(1);
     57   }
     58   static base::TimeDelta GetUpperEpsilonForTimeComparisons() {
     59     return base::TimeDelta();
     60   }
     61 
     62  private:
     63   friend class SimpleIndexFileTest;
     64 
     65   // When adding new members here, you should update the Serialize() and
     66   // Deserialize() methods.
     67 
     68   uint32 last_used_time_seconds_since_epoch_;
     69 
     70   int32 entry_size_;  // Storage size in bytes.
     71 };
     72 COMPILE_ASSERT(sizeof(EntryMetadata) == 8, metadata_size);
     73 
     74 // This class is not Thread-safe.
     75 class NET_EXPORT_PRIVATE SimpleIndex
     76     : public base::SupportsWeakPtr<SimpleIndex> {
     77  public:
     78   typedef std::vector<uint64> HashList;
     79 
     80   SimpleIndex(const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
     81               SimpleIndexDelegate* delegate,
     82               net::CacheType cache_type,
     83               scoped_ptr<SimpleIndexFile> simple_index_file);
     84 
     85   virtual ~SimpleIndex();
     86 
     87   void Initialize(base::Time cache_mtime);
     88 
     89   bool SetMaxSize(int max_bytes);
     90   int max_size() const { return max_size_; }
     91 
     92   void Insert(uint64 entry_hash);
     93   void Remove(uint64 entry_hash);
     94 
     95   // Check whether the index has the entry given the hash of its key.
     96   bool Has(uint64 entry_hash) const;
     97 
     98   // Update the last used time of the entry with the given key and return true
     99   // iff the entry exist in the index.
    100   bool UseIfExists(uint64 entry_hash);
    101 
    102   void WriteToDisk();
    103 
    104   // Update the size (in bytes) of an entry, in the metadata stored in the
    105   // index. This should be the total disk-file size including all streams of the
    106   // entry.
    107   bool UpdateEntrySize(uint64 entry_hash, int entry_size);
    108 
    109   typedef base::hash_map<uint64, EntryMetadata> EntrySet;
    110 
    111   static void InsertInEntrySet(uint64 entry_hash,
    112                                const EntryMetadata& entry_metadata,
    113                                EntrySet* entry_set);
    114 
    115   // Executes the |callback| when the index is ready. Allows multiple callbacks.
    116   int ExecuteWhenReady(const net::CompletionCallback& callback);
    117 
    118   // Returns entries from the index that have last accessed time matching the
    119   // range between |initial_time| and |end_time| where open intervals are
    120   // possible according to the definition given in |DoomEntriesBetween()| in the
    121   // disk cache backend interface.
    122   scoped_ptr<HashList> GetEntriesBetween(const base::Time initial_time,
    123                                          const base::Time end_time);
    124 
    125   // Returns the list of all entries key hash.
    126   scoped_ptr<HashList> GetAllHashes();
    127 
    128   // Returns number of indexed entries.
    129   int32 GetEntryCount() const;
    130 
    131   // Returns whether the index has been initialized yet.
    132   bool initialized() const { return initialized_; }
    133 
    134  private:
    135   friend class SimpleIndexTest;
    136   FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge);
    137   FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteQueued);
    138   FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteExecuted);
    139   FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWritePostponed);
    140 
    141   void StartEvictionIfNeeded();
    142   void EvictionDone(int result);
    143 
    144   void PostponeWritingToDisk();
    145 
    146   void UpdateEntryIteratorSize(EntrySet::iterator* it, int entry_size);
    147 
    148   // Must run on IO Thread.
    149   void MergeInitializingSet(scoped_ptr<SimpleIndexLoadResult> load_result);
    150 
    151 #if defined(OS_ANDROID)
    152   void OnApplicationStateChange(base::android::ApplicationState state);
    153 
    154   scoped_ptr<base::android::ApplicationStatusListener> app_status_listener_;
    155 #endif
    156 
    157   // The owner of |this| must ensure the |delegate_| outlives |this|.
    158   SimpleIndexDelegate* delegate_;
    159 
    160   EntrySet entries_set_;
    161 
    162   const net::CacheType cache_type_;
    163   uint64 cache_size_;  // Total cache storage size in bytes.
    164   uint64 max_size_;
    165   uint64 high_watermark_;
    166   uint64 low_watermark_;
    167   bool eviction_in_progress_;
    168   base::TimeTicks eviction_start_time_;
    169 
    170   // This stores all the entry_hash of entries that are removed during
    171   // initialization.
    172   base::hash_set<uint64> removed_entries_;
    173   bool initialized_;
    174 
    175   scoped_ptr<SimpleIndexFile> index_file_;
    176 
    177   scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
    178 
    179   // All nonstatic SimpleEntryImpl methods should always be called on the IO
    180   // thread, in all cases. |io_thread_checker_| documents and enforces this.
    181   base::ThreadChecker io_thread_checker_;
    182 
    183   // Timestamp of the last time we wrote the index to disk.
    184   // PostponeWritingToDisk() may give up postponing and allow the write if it
    185   // has been a while since last time we wrote.
    186   base::TimeTicks last_write_to_disk_;
    187 
    188   base::OneShotTimer<SimpleIndex> write_to_disk_timer_;
    189   base::Closure write_to_disk_cb_;
    190 
    191   typedef std::list<net::CompletionCallback> CallbackList;
    192   CallbackList to_run_when_initialized_;
    193 
    194   // Set to true when the app is on the background. When the app is in the
    195   // background we can write the index much more frequently, to insure fresh
    196   // index on next startup.
    197   bool app_on_background_;
    198 };
    199 
    200 }  // namespace disk_cache
    201 
    202 #endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
    203