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