Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(505)

Side by Side Diff: content/child/indexed_db/webidbcursor_impl.cc

Issue 1963293002: Replacing Indexed DB Chromium IPC with Mojo Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactoring after Passing URLRequestContextGetter. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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 #include "content/child/indexed_db/webidbcursor_impl.h"
6
7 #include <stddef.h>
8
9 #include <string>
10 #include <vector>
11
12 #include "content/child/indexed_db/indexed_db_dispatcher.h"
13 #include "content/child/indexed_db/indexed_db_key_builders.h"
14 #include "content/child/thread_safe_sender.h"
15 #include "content/common/indexed_db/indexed_db_messages.h"
16 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBValue.h"
17
18 using blink::WebBlobInfo;
19 using blink::WebData;
20 using blink::WebIDBCallbacks;
21 using blink::WebIDBKey;
22 using blink::WebIDBValue;
23
24 namespace content {
25
26 WebIDBCursorImpl::WebIDBCursorImpl(int32_t ipc_cursor_id,
27 int64_t transaction_id,
28 ThreadSafeSender* thread_safe_sender)
29 : ipc_cursor_id_(ipc_cursor_id),
30 transaction_id_(transaction_id),
31 continue_count_(0),
32 used_prefetches_(0),
33 pending_onsuccess_callbacks_(0),
34 prefetch_amount_(kMinPrefetchAmount),
35 thread_safe_sender_(thread_safe_sender) {}
36
37 WebIDBCursorImpl::~WebIDBCursorImpl() {
38 // It's not possible for there to be pending callbacks that address this
39 // object since inside WebKit, they hold a reference to the object which owns
40 // this object. But, if that ever changed, then we'd need to invalidate
41 // any such pointers.
42
43 if (ipc_cursor_id_ != kInvalidCursorId) {
44 // Invalid ID used in tests to avoid really sending this message.
45 thread_safe_sender_->Send(
46 new IndexedDBHostMsg_CursorDestroyed(ipc_cursor_id_));
47 }
48 IndexedDBDispatcher* dispatcher =
49 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get());
50 dispatcher->CursorDestroyed(ipc_cursor_id_);
51 }
52
53 void WebIDBCursorImpl::advance(unsigned long count,
54 WebIDBCallbacks* callbacks_ptr) {
55 IndexedDBDispatcher* dispatcher =
56 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get());
57 std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
58 if (count <= prefetch_keys_.size()) {
59 CachedAdvance(count, callbacks.get());
60 return;
61 }
62 ResetPrefetchCache();
63 dispatcher->RequestIDBCursorAdvance(
64 count, callbacks.release(), ipc_cursor_id_, transaction_id_);
65 }
66
67 void WebIDBCursorImpl::continueFunction(const WebIDBKey& key,
68 WebIDBCallbacks* callbacks_ptr) {
69 continueFunction(key, WebIDBKey::createNull(), callbacks_ptr);
70 }
71
72 void WebIDBCursorImpl::continueFunction(const WebIDBKey& key,
73 const WebIDBKey& primary_key,
74 WebIDBCallbacks* callbacks_ptr) {
75 IndexedDBDispatcher* dispatcher =
76 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get());
77 std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
78
79 if (key.keyType() == blink::WebIDBKeyTypeNull &&
80 primary_key.keyType() == blink::WebIDBKeyTypeNull) {
81 // No key(s), so this would qualify for a prefetch.
82 ++continue_count_;
83
84 if (!prefetch_keys_.empty()) {
85 // We have a prefetch cache, so serve the result from that.
86 CachedContinue(callbacks.get());
87 return;
88 }
89
90 if (continue_count_ > kPrefetchContinueThreshold) {
91 // Request pre-fetch.
92 ++pending_onsuccess_callbacks_;
93 dispatcher->RequestIDBCursorPrefetch(
94 prefetch_amount_, callbacks.release(), ipc_cursor_id_);
95
96 // Increase prefetch_amount_ exponentially.
97 prefetch_amount_ *= 2;
98 if (prefetch_amount_ > kMaxPrefetchAmount)
99 prefetch_amount_ = kMaxPrefetchAmount;
100
101 return;
102 }
103 } else {
104 // Key argument supplied. We couldn't prefetch this.
105 ResetPrefetchCache();
106 }
107
108 dispatcher->RequestIDBCursorContinue(IndexedDBKeyBuilder::Build(key),
109 IndexedDBKeyBuilder::Build(primary_key),
110 callbacks.release(),
111 ipc_cursor_id_,
112 transaction_id_);
113 }
114
115 void WebIDBCursorImpl::postSuccessHandlerCallback() {
116 pending_onsuccess_callbacks_--;
117
118 // If the onsuccess callback called continue()/advance() on the cursor
119 // again, and that request was served by the prefetch cache, then
120 // pending_onsuccess_callbacks_ would be incremented. If not, it means the
121 // callback did something else, or nothing at all, in which case we need to
122 // reset the cache.
123
124 if (pending_onsuccess_callbacks_ == 0)
125 ResetPrefetchCache();
126 }
127
128 void WebIDBCursorImpl::SetPrefetchData(
129 const std::vector<IndexedDBKey>& keys,
130 const std::vector<IndexedDBKey>& primary_keys,
131 const std::vector<WebIDBValue>& values) {
132 prefetch_keys_.assign(keys.begin(), keys.end());
133 prefetch_primary_keys_.assign(primary_keys.begin(), primary_keys.end());
134 prefetch_values_.assign(values.begin(), values.end());
135
136 used_prefetches_ = 0;
137 pending_onsuccess_callbacks_ = 0;
138 }
139
140 void WebIDBCursorImpl::CachedAdvance(unsigned long count,
141 WebIDBCallbacks* callbacks) {
142 DCHECK_GE(prefetch_keys_.size(), count);
143 DCHECK_EQ(prefetch_primary_keys_.size(), prefetch_keys_.size());
144 DCHECK_EQ(prefetch_values_.size(), prefetch_keys_.size());
145
146 while (count > 1) {
147 prefetch_keys_.pop_front();
148 prefetch_primary_keys_.pop_front();
149 prefetch_values_.pop_front();
150 ++used_prefetches_;
151 --count;
152 }
153
154 CachedContinue(callbacks);
155 }
156
157 void WebIDBCursorImpl::CachedContinue(WebIDBCallbacks* callbacks) {
158 DCHECK_GT(prefetch_keys_.size(), 0ul);
159 DCHECK_EQ(prefetch_primary_keys_.size(), prefetch_keys_.size());
160 DCHECK_EQ(prefetch_values_.size(), prefetch_keys_.size());
161
162 IndexedDBKey key = prefetch_keys_.front();
163 IndexedDBKey primary_key = prefetch_primary_keys_.front();
164 WebIDBValue value = prefetch_values_.front();
165
166 prefetch_keys_.pop_front();
167 prefetch_primary_keys_.pop_front();
168 prefetch_values_.pop_front();
169 ++used_prefetches_;
170
171 ++pending_onsuccess_callbacks_;
172
173 if (!continue_count_) {
174 // The cache was invalidated by a call to ResetPrefetchCache()
175 // after the RequestIDBCursorPrefetch() was made. Now that the
176 // initiating continue() call has been satisfied, discard
177 // the rest of the cache.
178 ResetPrefetchCache();
179 }
180
181 callbacks->onSuccess(WebIDBKeyBuilder::Build(key),
182 WebIDBKeyBuilder::Build(primary_key), value);
183 }
184
185 void WebIDBCursorImpl::ResetPrefetchCache() {
186 continue_count_ = 0;
187 prefetch_amount_ = kMinPrefetchAmount;
188
189 if (prefetch_keys_.empty()) {
190 // No prefetch cache, so no need to reset the cursor in the back-end.
191 return;
192 }
193
194 // Ack any unused blobs.
195 std::vector<std::string> uuids;
196 for (const auto& value : prefetch_values_) {
197 for (size_t i = 0, size = value.webBlobInfo.size(); i < size; ++i)
198 uuids.push_back(value.webBlobInfo[i].uuid().latin1());
199 }
200 if (!uuids.empty())
201 thread_safe_sender_->Send(new IndexedDBHostMsg_AckReceivedBlobs(uuids));
202
203 // Reset the back-end cursor.
204 IndexedDBDispatcher* dispatcher =
205 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get());
206 dispatcher->RequestIDBCursorPrefetchReset(
207 used_prefetches_, prefetch_keys_.size(), ipc_cursor_id_);
208
209 // Reset the prefetch cache.
210 prefetch_keys_.clear();
211 prefetch_primary_keys_.clear();
212 prefetch_values_.clear();
213
214 pending_onsuccess_callbacks_ = 0;
215 }
216
217 } // namespace content
OLDNEW
« no previous file with comments | « content/child/indexed_db/webidbcursor_impl.h ('k') | content/child/indexed_db/webidbcursor_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698