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