• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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_MEMORY_MEM_ENTRY_IMPL_H_
6 #define NET_DISK_CACHE_MEMORY_MEM_ENTRY_IMPL_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "base/containers/linked_list.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/time/time.h"
20 #include "base/trace_event/memory_usage_estimator.h"
21 #include "net/base/interval.h"
22 #include "net/base/net_export.h"
23 #include "net/disk_cache/disk_cache.h"
24 #include "net/log/net_log_with_source.h"
25 
26 namespace net {
27 class NetLog;
28 }
29 
30 namespace disk_cache {
31 
32 class MemBackendImpl;
33 
34 // This class implements the Entry interface for the memory-only cache. An
35 // object of this class represents a single entry on the cache. We use two types
36 // of entries, parent and child to support sparse caching.
37 //
38 // A parent entry is non-sparse until a sparse method is invoked (i.e.
39 // ReadSparseData, WriteSparseData, GetAvailableRange) when sparse information
40 // is initialized. It then manages a list of child entries and delegates the
41 // sparse API calls to the child entries. It creates and deletes child entries
42 // and updates the list when needed.
43 //
44 // A child entry is used to carry partial cache content, non-sparse methods like
45 // ReadData and WriteData cannot be applied to them. The lifetime of a child
46 // entry is managed by the parent entry that created it except that the entry
47 // can be evicted independently. A child entry does not have a key and it is not
48 // registered in the backend's entry map.
49 //
50 // A sparse child entry has a fixed maximum size and can be partially
51 // filled. There can only be one continous filled region in a sparse entry, as
52 // illustrated by the following example:
53 // | xxx ooooo |
54 // x = unfilled region
55 // o = filled region
56 // It is guaranteed that there is at most one unfilled region and one filled
57 // region, and the unfilled region (if there is one) is always before the filled
58 // region. The book keeping for filled region in a sparse entry is done by using
59 // the variable |child_first_pos_|.
60 
61 class NET_EXPORT_PRIVATE MemEntryImpl final
62     : public Entry,
63       public base::LinkNode<MemEntryImpl> {
64  public:
65   enum class EntryType {
66     kParent,
67     kChild,
68   };
69 
70   // Provided to better document calls to |UpdateStateOnUse()|.
71   enum EntryModified {
72     ENTRY_WAS_NOT_MODIFIED,
73     ENTRY_WAS_MODIFIED,
74   };
75 
76   // Constructor for parent entries.
77   MemEntryImpl(base::WeakPtr<MemBackendImpl> backend,
78                const std::string& key,
79                net::NetLog* net_log);
80 
81   // Constructor for child entries.
82   MemEntryImpl(base::WeakPtr<MemBackendImpl> backend,
83                int64_t child_id,
84                MemEntryImpl* parent,
85                net::NetLog* net_log);
86 
87   MemEntryImpl(const MemEntryImpl&) = delete;
88   MemEntryImpl& operator=(const MemEntryImpl&) = delete;
89 
90   void Open();
91   bool InUse() const;
92 
type()93   EntryType type() const {
94     return parent_ ? EntryType::kChild : EntryType::kParent;
95   }
key()96   const std::string& key() const { return key_; }
parent()97   const MemEntryImpl* parent() const { return parent_; }
child_id()98   int64_t child_id() const { return child_id_; }
last_used()99   base::Time last_used() const { return last_used_; }
100 
101   // The in-memory size of this entry to use for the purposes of eviction.
102   int GetStorageSize() const;
103 
104   // Update an entry's position in the backend LRU list and set |last_used_|. If
105   // the entry was modified, also update |last_modified_|.
106   void UpdateStateOnUse(EntryModified modified_enum);
107 
108   // From disk_cache::Entry:
109   void Doom() override;
110   void Close() override;
111   std::string GetKey() const override;
112   base::Time GetLastUsed() const override;
113   base::Time GetLastModified() const override;
114   int32_t GetDataSize(int index) const override;
115   int ReadData(int index,
116                int offset,
117                IOBuffer* buf,
118                int buf_len,
119                CompletionOnceCallback callback) override;
120   int WriteData(int index,
121                 int offset,
122                 IOBuffer* buf,
123                 int buf_len,
124                 CompletionOnceCallback callback,
125                 bool truncate) override;
126   int ReadSparseData(int64_t offset,
127                      IOBuffer* buf,
128                      int buf_len,
129                      CompletionOnceCallback callback) override;
130   int WriteSparseData(int64_t offset,
131                       IOBuffer* buf,
132                       int buf_len,
133                       CompletionOnceCallback callback) override;
134   RangeResult GetAvailableRange(int64_t offset,
135                                 int len,
136                                 RangeResultCallback callback) override;
137   bool CouldBeSparse() const override;
CancelSparseIO()138   void CancelSparseIO() override {}
139   net::Error ReadyForSparseIO(CompletionOnceCallback callback) override;
140   void SetLastUsedTimeForTest(base::Time time) override;
141 
142  private:
143   MemEntryImpl(base::WeakPtr<MemBackendImpl> backend,
144                const std::string& key,
145                int64_t child_id,
146                MemEntryImpl* parent,
147                net::NetLog* net_log);
148 
149   using EntryMap = std::map<int64_t, MemEntryImpl*>;
150 
151   static const int kNumStreams = 3;
152 
153   ~MemEntryImpl() override;
154 
155   // Do all the work for corresponding public functions.  Implemented as
156   // separate functions to make logging of results simpler.
157   int InternalReadData(int index, int offset, IOBuffer* buf, int buf_len);
158   int InternalWriteData(int index, int offset, IOBuffer* buf, int buf_len,
159                         bool truncate);
160   int InternalReadSparseData(int64_t offset, IOBuffer* buf, int buf_len);
161   int InternalWriteSparseData(int64_t offset, IOBuffer* buf, int buf_len);
162   RangeResult InternalGetAvailableRange(int64_t offset, int len);
163 
164   // Initializes the children map and sparse info. This method is only called
165   // on a parent entry.
166   bool InitSparseInfo();
167 
168   // Returns an entry responsible for |offset|. The returned entry can be a
169   // child entry or this entry itself if |offset| points to the first range.
170   // If such entry does not exist and |create| is true, a new child entry is
171   // created.
172   MemEntryImpl* GetChild(int64_t offset, bool create);
173 
174   // Returns an interval describing what's stored in the child entry pointed to
175   // by i, in global coordinates.
176   // Precondition: i != children_.end();
177   net::Interval<int64_t> ChildInterval(
178       MemEntryImpl::EntryMap::const_iterator i);
179 
180   // Compact vectors to try to avoid over-allocation due to exponential growth.
181   void Compact();
182 
183   std::string key_;
184   std::vector<char> data_[kNumStreams];  // User data.
185   uint32_t ref_count_ = 0;
186 
187   int64_t child_id_;     // The ID of a child entry.
188   int child_first_pos_ = 0;  // The position of the first byte in a child
189                              // entry. 0 here is beginning of child, not of
190                              // the entire file.
191   // Pointer to the parent entry, or nullptr if this entry is a parent entry.
192   raw_ptr<MemEntryImpl> parent_;
193   std::unique_ptr<EntryMap> children_;
194 
195   base::Time last_modified_;
196   base::Time last_used_;
197   base::WeakPtr<MemBackendImpl> backend_;  // Back pointer to the cache.
198   bool doomed_ = false;  // True if this entry was removed from the cache.
199 
200   net::NetLogWithSource net_log_;
201 };
202 
203 }  // namespace disk_cache
204 
205 #endif  // NET_DISK_CACHE_MEMORY_MEM_ENTRY_IMPL_H_
206