Home | History | Annotate | Download | only in disk_cache
      1 // Copyright (c) 2012 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_MEM_ENTRY_IMPL_H_
      6 #define NET_DISK_CACHE_MEM_ENTRY_IMPL_H_
      7 
      8 #include "base/containers/hash_tables.h"
      9 #include "base/gtest_prod_util.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "net/base/net_log.h"
     12 #include "net/disk_cache/disk_cache.h"
     13 
     14 namespace disk_cache {
     15 
     16 class MemBackendImpl;
     17 
     18 // This class implements the Entry interface for the memory-only cache. An
     19 // object of this class represents a single entry on the cache. We use two
     20 // types of entries, parent and child to support sparse caching.
     21 //
     22 // A parent entry is non-sparse until a sparse method is invoked (i.e.
     23 // ReadSparseData, WriteSparseData, GetAvailableRange) when sparse information
     24 // is initialized. It then manages a list of child entries and delegates the
     25 // sparse API calls to the child entries. It creates and deletes child entries
     26 // and updates the list when needed.
     27 //
     28 // A child entry is used to carry partial cache content, non-sparse methods like
     29 // ReadData and WriteData cannot be applied to them. The lifetime of a child
     30 // entry is managed by the parent entry that created it except that the entry
     31 // can be evicted independently. A child entry does not have a key and it is not
     32 // registered in the backend's entry map. It is registered in the backend's
     33 // ranking list to enable eviction of a partial content.
     34 //
     35 // A sparse entry has a fixed maximum size and can be partially filled. There
     36 // can only be one continous filled region in a sparse entry, as illustrated by
     37 // the following example:
     38 // | xxx ooooo |
     39 // x = unfilled region
     40 // o = filled region
     41 // It is guranteed that there is at most one unfilled region and one filled
     42 // region, and the unfilled region (if there is one) is always before the filled
     43 // region. The book keeping for filled region in a sparse entry is done by using
     44 // the variable |child_first_pos_| (inclusive).
     45 
     46 class MemEntryImpl : public Entry {
     47  public:
     48   enum EntryType {
     49     kParentEntry,
     50     kChildEntry,
     51   };
     52 
     53   explicit MemEntryImpl(MemBackendImpl* backend);
     54 
     55   // Performs the initialization of a EntryImpl that will be added to the
     56   // cache.
     57   bool CreateEntry(const std::string& key, net::NetLog* net_log);
     58 
     59   // Permanently destroys this entry.
     60   void InternalDoom();
     61 
     62   void Open();
     63   bool InUse();
     64 
     65   MemEntryImpl* next() const {
     66     return next_;
     67   }
     68 
     69   MemEntryImpl* prev() const {
     70     return prev_;
     71   }
     72 
     73   void set_next(MemEntryImpl* next) {
     74     next_ = next;
     75   }
     76 
     77   void set_prev(MemEntryImpl* prev) {
     78     prev_ = prev;
     79   }
     80 
     81   EntryType type() const {
     82     return parent_ ? kChildEntry : kParentEntry;
     83   }
     84 
     85   std::string& key() {
     86     return key_;
     87   }
     88 
     89   net::BoundNetLog& net_log() {
     90     return net_log_;
     91   }
     92 
     93   // Entry interface.
     94   virtual void Doom() OVERRIDE;
     95   virtual void Close() OVERRIDE;
     96   virtual std::string GetKey() const OVERRIDE;
     97   virtual base::Time GetLastUsed() const OVERRIDE;
     98   virtual base::Time GetLastModified() const OVERRIDE;
     99   virtual int32 GetDataSize(int index) const OVERRIDE;
    100   virtual int ReadData(int index, int offset, IOBuffer* buf, int buf_len,
    101                        const CompletionCallback& callback) OVERRIDE;
    102   virtual int WriteData(int index, int offset, IOBuffer* buf, int buf_len,
    103                         const CompletionCallback& callback,
    104                         bool truncate) OVERRIDE;
    105   virtual int ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
    106                              const CompletionCallback& callback) OVERRIDE;
    107   virtual int WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
    108                               const CompletionCallback& callback) OVERRIDE;
    109   virtual int GetAvailableRange(int64 offset, int len, int64* start,
    110                                 const CompletionCallback& callback) OVERRIDE;
    111   virtual bool CouldBeSparse() const OVERRIDE;
    112   virtual void CancelSparseIO() OVERRIDE {}
    113   virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE;
    114 
    115  private:
    116   typedef base::hash_map<int, MemEntryImpl*> EntryMap;
    117 
    118   enum {
    119     NUM_STREAMS = 3
    120   };
    121 
    122   virtual ~MemEntryImpl();
    123 
    124   // Do all the work for corresponding public functions.  Implemented as
    125   // separate functions to make logging of results simpler.
    126   int InternalReadData(int index, int offset, IOBuffer* buf, int buf_len);
    127   int InternalWriteData(int index, int offset, IOBuffer* buf, int buf_len,
    128                         bool truncate);
    129   int InternalReadSparseData(int64 offset, IOBuffer* buf, int buf_len);
    130   int InternalWriteSparseData(int64 offset, IOBuffer* buf, int buf_len);
    131 
    132   // Old Entry interface.
    133   int GetAvailableRange(int64 offset, int len, int64* start);
    134 
    135   // Grows and cleans up the data buffer.
    136   void PrepareTarget(int index, int offset, int buf_len);
    137 
    138   // Updates ranking information.
    139   void UpdateRank(bool modified);
    140 
    141   // Initializes the children map and sparse info. This method is only called
    142   // on a parent entry.
    143   bool InitSparseInfo();
    144 
    145   // Performs the initialization of a MemEntryImpl as a child entry.
    146   // |parent| is the pointer to the parent entry. |child_id| is the ID of
    147   // the new child.
    148   bool InitChildEntry(MemEntryImpl* parent, int child_id, net::NetLog* net_log);
    149 
    150   // Returns an entry responsible for |offset|. The returned entry can be a
    151   // child entry or this entry itself if |offset| points to the first range.
    152   // If such entry does not exist and |create| is true, a new child entry is
    153   // created.
    154   MemEntryImpl* OpenChild(int64 offset, bool create);
    155 
    156   // Finds the first child located within the range [|offset|, |offset + len|).
    157   // Returns the number of bytes ahead of |offset| to reach the first available
    158   // bytes in the entry. The first child found is output to |child|.
    159   int FindNextChild(int64 offset, int len, MemEntryImpl** child);
    160 
    161   // Removes child indexed by |child_id| from the children map.
    162   void DetachChild(int child_id);
    163 
    164   std::string key_;
    165   std::vector<char> data_[NUM_STREAMS];  // User data.
    166   int32 data_size_[NUM_STREAMS];
    167   int ref_count_;
    168 
    169   int child_id_;              // The ID of a child entry.
    170   int child_first_pos_;       // The position of the first byte in a child
    171                               // entry.
    172   MemEntryImpl* next_;        // Pointers for the LRU list.
    173   MemEntryImpl* prev_;
    174   MemEntryImpl* parent_;      // Pointer to the parent entry.
    175   scoped_ptr<EntryMap> children_;
    176 
    177   base::Time last_modified_;  // LRU information.
    178   base::Time last_used_;
    179   MemBackendImpl* backend_;   // Back pointer to the cache.
    180   bool doomed_;               // True if this entry was removed from the cache.
    181 
    182   net::BoundNetLog net_log_;
    183 
    184   DISALLOW_COPY_AND_ASSIGN(MemEntryImpl);
    185 };
    186 
    187 }  // namespace disk_cache
    188 
    189 #endif  // NET_DISK_CACHE_MEM_ENTRY_IMPL_H_
    190