summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/simple/simple_backend_impl.h
blob: a21c3c7582115d7dc1e5339eb2a63f1a02cbe057 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_

#include <string>
#include <utility>
#include <vector>

#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task_runner.h"
#include "net/base/cache_type.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/simple/simple_entry_impl.h"

namespace base {
class SingleThreadTaskRunner;
class TaskRunner;
}

namespace disk_cache {

// SimpleBackendImpl is a new cache backend that stores entries in individual
// files.

// It is currently a work in progress, missing many features of a real cache,
// such as eviction.

// See http://www.chromium.org/developers/design-documents/network-stack/disk-cache/very-simple-backend

class SimpleEntryImpl;
class SimpleIndex;

class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
    public base::SupportsWeakPtr<SimpleBackendImpl> {
 public:
  SimpleBackendImpl(const base::FilePath& path, int max_bytes,
                    net::CacheType type,
                    base::SingleThreadTaskRunner* cache_thread,
                    net::NetLog* net_log);

  virtual ~SimpleBackendImpl();

  SimpleIndex* index() { return index_.get(); }

  base::TaskRunner* worker_pool() { return worker_pool_.get(); }

  // Must run on IO Thread.
  int Init(const CompletionCallback& completion_callback);

  // Sets the maximum size for the total amount of data stored by this instance.
  bool SetMaxSize(int max_bytes);

  // Returns the maximum file size permitted in this backend.
  int GetMaxFileSize() const;

  // Removes |entry| from the |active_entries_| set, forcing future Open/Create
  // operations to construct a new object.
  void OnDeactivated(const SimpleEntryImpl* entry);

  // From Backend:
  virtual net::CacheType GetCacheType() const OVERRIDE;
  virtual int32 GetEntryCount() const OVERRIDE;
  virtual int OpenEntry(const std::string& key, Entry** entry,
                        const CompletionCallback& callback) OVERRIDE;
  virtual int CreateEntry(const std::string& key, Entry** entry,
                          const CompletionCallback& callback) OVERRIDE;
  virtual int DoomEntry(const std::string& key,
                        const CompletionCallback& callback) OVERRIDE;
  virtual int DoomAllEntries(const CompletionCallback& callback) OVERRIDE;
  virtual int DoomEntriesBetween(base::Time initial_time,
                                 base::Time end_time,
                                 const CompletionCallback& callback) OVERRIDE;
  virtual int DoomEntriesSince(base::Time initial_time,
                               const CompletionCallback& callback) OVERRIDE;
  virtual int OpenNextEntry(void** iter, Entry** next_entry,
                            const CompletionCallback& callback) OVERRIDE;
  virtual void EndEnumeration(void** iter) OVERRIDE;
  virtual void GetStats(
      std::vector<std::pair<std::string, std::string> >* stats) OVERRIDE;
  virtual void OnExternalCacheHit(const std::string& key) OVERRIDE;

 private:
  typedef base::hash_map<uint64, base::WeakPtr<SimpleEntryImpl> > EntryMap;

  typedef base::Callback<void(uint64 max_size, int result)>
      InitializeIndexCallback;

  // Must run on IO Thread.
  void InitializeIndex(const CompletionCallback& callback,
                       uint64 suggested_max_size,
                       int result);

  // Dooms all entries previously accessed between |initial_time| and
  // |end_time|. Invoked when the index is ready.
  void IndexReadyForDoom(base::Time initial_time,
                         base::Time end_time,
                         const CompletionCallback& callback,
                         int result);

  // Try to create the directory if it doesn't exist. Replies with maximum cache
  // size adjustment. Must run on Cache Thread.
  static void ProvideDirectorySuggestBetterCacheSize(
      base::SingleThreadTaskRunner* io_thread,
      const base::FilePath& path,
      const InitializeIndexCallback& initialize_index_callback,
      uint64 suggested_max_size);

  // Searches |active_entries_| for the entry corresponding to |key|. If found,
  // returns the found entry. Otherwise, creates a new entry and returns that.
  scoped_refptr<SimpleEntryImpl> CreateOrFindActiveEntry(
      const std::string& key);

  // Given a hash, will try to open the corresponding Entry. If we have an Entry
  // corresponding to |hash| in the map of active entries, opens it. Otherwise,
  // a new empty Entry will be created, opened and filled with information from
  // the disk.
  int OpenEntryFromHash(uint64 hash,
                        Entry** entry,
                        const CompletionCallback& callback);

  // Called when the index is initilized to find the next entry in the iterator
  // |iter|. If there are no more hashes in the iterator list, net::ERR_FAILED
  // is returned. Otherwise, calls OpenEntryFromHash.
  void GetNextEntryInIterator(void** iter,
                              Entry** next_entry,
                              const CompletionCallback& callback,
                              int error_code);

  // Called when we tried to open an entry with hash alone. When a blank entry
  // has been created and filled in with information from the disk - based on a
  // hash alone - this checks that a duplicate active entry was not created
  // using a key in the meantime.
  void OnEntryOpenedFromHash(uint64 hash,
                             Entry** entry,
                             scoped_refptr<SimpleEntryImpl> simple_entry,
                             const CompletionCallback& callback,
                             int error_code);

  // Called when we tried to open an entry from key. When the entry has been
  // opened, a check for key mismatch is performed.
  void OnEntryOpenedFromKey(const std::string key,
                            Entry** entry,
                            scoped_refptr<SimpleEntryImpl> simple_entry,
                            const CompletionCallback& callback,
                            int error_code);

  // Called at the end of the asynchronous operation triggered by
  // OpenEntryFromHash. Makes sure to continue iterating if the open entry was
  // not a success.
  void CheckIterationReturnValue(void** iter,
                                 Entry** entry,
                                 const CompletionCallback& callback,
                                 int error_code);

  const base::FilePath path_;
  scoped_ptr<SimpleIndex> index_;
  const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_;
  scoped_refptr<base::TaskRunner> worker_pool_;

  int orig_max_size_;
  const SimpleEntryImpl::OperationsMode entry_operations_mode_;

  // TODO(gavinp): Store the entry_hash in SimpleEntryImpl, and index this map
  // by hash. This will save memory, and make IndexReadyForDoom easier.
  EntryMap active_entries_;

  net::NetLog* const net_log_;
};

}  // namespace disk_cache

#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_