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