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 |