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_FILE_H_
      6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/containers/hash_tables.h"
     13 #include "base/files/file_path.h"
     14 #include "base/gtest_prod_util.h"
     15 #include "base/logging.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "base/pickle.h"
     18 #include "base/port.h"
     19 #include "net/base/net_export.h"
     20 #include "net/disk_cache/simple/simple_index.h"
     21 
     22 namespace base {
     23 class SingleThreadTaskRunner;
     24 class TaskRunner;
     25 }
     26 
     27 namespace disk_cache {
     28 
     29 const uint64 kSimpleIndexMagicNumber = GG_UINT64_C(0x656e74657220796f);
     30 
     31 struct NET_EXPORT_PRIVATE SimpleIndexLoadResult {
     32   SimpleIndexLoadResult();
     33   ~SimpleIndexLoadResult();
     34   void Reset();
     35 
     36   bool did_load;
     37   SimpleIndex::EntrySet entries;
     38   bool flush_required;
     39 };
     40 
     41 // Simple Index File format is a pickle serialized data of IndexMetadata and
     42 // EntryMetadata objects.  The file format is as follows: one instance of
     43 // serialized |IndexMetadata| followed serialized |EntryMetadata| entries
     44 // repeated |number_of_entries| amount of times.  To know more about the format,
     45 // see SimpleIndexFile::Serialize() and SeeSimpleIndexFile::LoadFromDisk()
     46 // methods.
     47 //
     48 // The non-static methods must run on the IO thread.  All the real
     49 // work is done in the static methods, which are run on the cache thread
     50 // or in worker threads.  Synchronization between methods is the
     51 // responsibility of the caller.
     52 class NET_EXPORT_PRIVATE SimpleIndexFile {
     53  public:
     54   class NET_EXPORT_PRIVATE IndexMetadata {
     55    public:
     56     IndexMetadata();
     57     IndexMetadata(uint64 number_of_entries, uint64 cache_size);
     58 
     59     void Serialize(Pickle* pickle) const;
     60     bool Deserialize(PickleIterator* it);
     61 
     62     bool CheckIndexMetadata();
     63 
     64     uint64 GetNumberOfEntries() { return number_of_entries_; }
     65 
     66    private:
     67     FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics);
     68     FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize);
     69 
     70     uint64 magic_number_;
     71     uint32 version_;
     72     uint64 number_of_entries_;
     73     uint64 cache_size_;  // Total cache storage size in bytes.
     74   };
     75 
     76   SimpleIndexFile(base::SingleThreadTaskRunner* cache_thread,
     77                   base::TaskRunner* worker_pool,
     78                   const base::FilePath& cache_directory);
     79   virtual ~SimpleIndexFile();
     80 
     81   // Get index entries based on current disk context.
     82   virtual void LoadIndexEntries(base::Time cache_last_modified,
     83                                 const base::Closure& callback,
     84                                 SimpleIndexLoadResult* out_result);
     85 
     86   // Write the specified set of entries to disk.
     87   virtual void WriteToDisk(const SimpleIndex::EntrySet& entry_set,
     88                            uint64 cache_size,
     89                            const base::TimeTicks& start,
     90                            bool app_on_background);
     91 
     92   // Doom the entries specified in |entry_hashes|, calling |reply_callback|
     93   // with the result on the current thread when done.
     94   virtual void DoomEntrySet(scoped_ptr<std::vector<uint64> > entry_hashes,
     95                             const base::Callback<void(int)>& reply_callback);
     96 
     97  private:
     98   friend class WrappedSimpleIndexFile;
     99 
    100   // Used for cache directory traversal.
    101   typedef base::Callback<void (const base::FilePath&)> EntryFileCallback;
    102 
    103   // When loading the entries from disk, add this many extra hash buckets to
    104   // prevent reallocation on the IO thread when merging in new live entries.
    105   static const int kExtraSizeForMerge = 512;
    106 
    107   // Synchronous (IO performing) implementation of LoadIndexEntries.
    108   static void SyncLoadIndexEntries(base::Time cache_last_modified,
    109                                    const base::FilePath& cache_directory,
    110                                    const base::FilePath& index_file_path,
    111                                    SimpleIndexLoadResult* out_result);
    112 
    113   // Load the index file from disk returning an EntrySet. Upon failure, returns
    114   // NULL.
    115   static void SyncLoadFromDisk(const base::FilePath& index_filename,
    116                                SimpleIndexLoadResult* out_result);
    117 
    118   // Returns a scoped_ptr for a newly allocated Pickle containing the serialized
    119   // data to be written to a file.
    120   static scoped_ptr<Pickle> Serialize(
    121       const SimpleIndexFile::IndexMetadata& index_metadata,
    122       const SimpleIndex::EntrySet& entries);
    123 
    124   // Given the contents of an index file |data| of length |data_len|, returns
    125   // the corresponding EntrySet. Returns NULL on error.
    126   static void Deserialize(const char* data, int data_len,
    127                           SimpleIndexLoadResult* out_result);
    128 
    129   // Implemented either in simple_index_file_posix.cc or
    130   // simple_index_file_win.cc. base::FileEnumerator turned out to be very
    131   // expensive in terms of memory usage therefore it's used only on non-POSIX
    132   // environments for convenience (for now). Returns whether the traversal
    133   // succeeded.
    134   static bool TraverseCacheDirectory(
    135       const base::FilePath& cache_path,
    136       const EntryFileCallback& entry_file_callback);
    137 
    138   // Scan the index directory for entries, returning an EntrySet of all entries
    139   // found.
    140   static void SyncRestoreFromDisk(const base::FilePath& cache_directory,
    141                                   const base::FilePath& index_file_path,
    142                                   SimpleIndexLoadResult* out_result);
    143 
    144   // Determines if an index file is stale relative to the time of last
    145   // modification of the cache directory.
    146   static bool IsIndexFileStale(base::Time cache_last_modified,
    147                                const base::FilePath& index_file_path);
    148 
    149   struct PickleHeader : public Pickle::Header {
    150     uint32 crc;
    151   };
    152 
    153   const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_;
    154   const scoped_refptr<base::TaskRunner> worker_pool_;
    155   const base::FilePath cache_directory_;
    156   const base::FilePath index_file_;
    157   const base::FilePath temp_index_file_;
    158 
    159   DISALLOW_COPY_AND_ASSIGN(SimpleIndexFile);
    160 };
    161 
    162 
    163 }  // namespace disk_cache
    164 
    165 #endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
    166