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
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_DISK_CACHE_H_
6#define CONTENT_BROWSER_APPCACHE_APPCACHE_DISK_CACHE_H_
7
8#include <set>
9#include <vector>
10
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "content/browser/appcache/appcache_response.h"
14#include "content/common/content_export.h"
15#include "net/disk_cache/disk_cache.h"
16
17namespace base {
18class SingleThreadTaskRunner;
19}  // namespace base
20
21namespace content {
22
23// An implementation of AppCacheDiskCacheInterface that
24// uses net::DiskCache as the backing store.
25class CONTENT_EXPORT AppCacheDiskCache
26    : public AppCacheDiskCacheInterface {
27 public:
28  AppCacheDiskCache();
29  virtual ~AppCacheDiskCache();
30
31  // Initializes the object to use disk backed storage.
32  int InitWithDiskBackend(
33      const base::FilePath& disk_cache_directory,
34      int disk_cache_size,
35      bool force,
36      const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
37      const net::CompletionCallback& callback);
38
39  // Initializes the object to use memory only storage.
40  // This is used for Chrome's incognito browsing.
41  int InitWithMemBackend(int disk_cache_size,
42                         const net::CompletionCallback& callback);
43
44  void Disable();
45  bool is_disabled() const { return is_disabled_; }
46
47  virtual int CreateEntry(int64 key, Entry** entry,
48                          const net::CompletionCallback& callback) OVERRIDE;
49  virtual int OpenEntry(int64 key, Entry** entry,
50                        const net::CompletionCallback& callback) OVERRIDE;
51  virtual int DoomEntry(int64 key,
52                        const net::CompletionCallback& callback) OVERRIDE;
53
54 private:
55  class CreateBackendCallbackShim;
56  class EntryImpl;
57
58  // PendingCalls allow CreateEntry, OpenEntry, and DoomEntry to be called
59  // immediately after construction, without waiting for the
60  // underlying disk_cache::Backend to be fully constructed. Early
61  // calls are queued up and serviced once the disk_cache::Backend is
62  // really ready to go.
63  enum PendingCallType {
64    CREATE,
65    OPEN,
66    DOOM
67  };
68  struct PendingCall {
69    PendingCallType call_type;
70    int64 key;
71    Entry** entry;
72    net::CompletionCallback callback;
73
74    PendingCall();
75
76    PendingCall(PendingCallType call_type, int64 key,
77                Entry** entry, const net::CompletionCallback& callback);
78
79    ~PendingCall();
80  };
81  typedef std::vector<PendingCall> PendingCalls;
82
83  class ActiveCall;
84  typedef std::set<ActiveCall*> ActiveCalls;
85  typedef std::set<EntryImpl*> OpenEntries;
86
87  bool is_initializing() const {
88    return create_backend_callback_.get() != NULL;
89  }
90  disk_cache::Backend* disk_cache() { return disk_cache_.get(); }
91  int Init(net::CacheType cache_type,
92           const base::FilePath& directory,
93           int cache_size,
94           bool force,
95           const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
96           const net::CompletionCallback& callback);
97  void OnCreateBackendComplete(int rv);
98  void AddActiveCall(ActiveCall* call) { active_calls_.insert(call); }
99  void RemoveActiveCall(ActiveCall* call) { active_calls_.erase(call); }
100  void AddOpenEntry(EntryImpl* entry) { open_entries_.insert(entry); }
101  void RemoveOpenEntry(EntryImpl* entry) { open_entries_.erase(entry); }
102
103  bool is_disabled_;
104  net::CompletionCallback init_callback_;
105  scoped_refptr<CreateBackendCallbackShim> create_backend_callback_;
106  PendingCalls pending_calls_;
107  ActiveCalls active_calls_;
108  OpenEntries open_entries_;
109  scoped_ptr<disk_cache::Backend> disk_cache_;
110};
111
112}  // namespace content
113
114#endif  // CONTENT_BROWSER_APPCACHE_APPCACHE_DISK_CACHE_H_
115