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

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

Issue 104663007: IndexedDB: Optimize IDBCursor.advance() if it occurs within prefetched range (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added comments about virtual usage Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « content/child/indexed_db/webidbcursor_impl.cc ('k') | content/child/thread_safe_sender.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 #include "base/memory/scoped_ptr.h" 5 #include "base/memory/scoped_ptr.h"
6 #include "base/values.h" 6 #include "base/values.h"
7 #include "content/child/indexed_db/indexed_db_dispatcher.h" 7 #include "content/child/indexed_db/indexed_db_dispatcher.h"
8 #include "content/child/indexed_db/indexed_db_key_builders.h" 8 #include "content/child/indexed_db/indexed_db_key_builders.h"
9 #include "content/child/indexed_db/webidbcursor_impl.h" 9 #include "content/child/indexed_db/webidbcursor_impl.h"
10 #include "content/child/thread_safe_sender.h" 10 #include "content/child/thread_safe_sender.h"
(...skipping 12 matching lines...) Expand all
23 namespace content { 23 namespace content {
24 24
25 namespace { 25 namespace {
26 26
27 class MockDispatcher : public IndexedDBDispatcher { 27 class MockDispatcher : public IndexedDBDispatcher {
28 public: 28 public:
29 MockDispatcher(ThreadSafeSender* thread_safe_sender) 29 MockDispatcher(ThreadSafeSender* thread_safe_sender)
30 : IndexedDBDispatcher(thread_safe_sender), 30 : IndexedDBDispatcher(thread_safe_sender),
31 prefetch_calls_(0), 31 prefetch_calls_(0),
32 last_prefetch_count_(0), 32 last_prefetch_count_(0),
33 advance_calls_(0),
33 continue_calls_(0), 34 continue_calls_(0),
34 destroyed_cursor_id_(0) {} 35 destroyed_cursor_id_(0) {}
35 36
36 virtual void RequestIDBCursorPrefetch(int n, 37 virtual void RequestIDBCursorPrefetch(int n,
37 WebIDBCallbacks* callbacks, 38 WebIDBCallbacks* callbacks,
38 int32 ipc_cursor_id) OVERRIDE { 39 int32 ipc_cursor_id) OVERRIDE {
39 ++prefetch_calls_; 40 ++prefetch_calls_;
40 last_prefetch_count_ = n; 41 last_prefetch_count_ = n;
41 callbacks_.reset(callbacks); 42 callbacks_.reset(callbacks);
42 } 43 }
43 44
45 virtual void RequestIDBCursorAdvance(unsigned long count,
46 WebIDBCallbacks* callbacks,
47 int32 ipc_cursor_id) OVERRIDE {
48 ++advance_calls_;
49 callbacks_.reset(callbacks);
50 }
51
44 virtual void RequestIDBCursorContinue(const IndexedDBKey& key, 52 virtual void RequestIDBCursorContinue(const IndexedDBKey& key,
45 const IndexedDBKey& primary_key, 53 const IndexedDBKey& primary_key,
46 WebIDBCallbacks* callbacks, 54 WebIDBCallbacks* callbacks,
47 int32 ipc_cursor_id) OVERRIDE { 55 int32 ipc_cursor_id) OVERRIDE {
48 ++continue_calls_; 56 ++continue_calls_;
49 callbacks_.reset(callbacks); 57 callbacks_.reset(callbacks);
50 } 58 }
51 59
52 virtual void CursorDestroyed(int32 ipc_cursor_id) OVERRIDE { 60 virtual void CursorDestroyed(int32 ipc_cursor_id) OVERRIDE {
53 destroyed_cursor_id_ = ipc_cursor_id; 61 destroyed_cursor_id_ = ipc_cursor_id;
54 } 62 }
55 63
56 int prefetch_calls() { return prefetch_calls_; } 64 int prefetch_calls() { return prefetch_calls_; }
65 int advance_calls() { return advance_calls_; }
57 int continue_calls() { return continue_calls_; } 66 int continue_calls() { return continue_calls_; }
58 int last_prefetch_count() { return last_prefetch_count_; } 67 int last_prefetch_count() { return last_prefetch_count_; }
59 int32 destroyed_cursor_id() { return destroyed_cursor_id_; } 68 int32 destroyed_cursor_id() { return destroyed_cursor_id_; }
60 69
61 private: 70 private:
62 int prefetch_calls_; 71 int prefetch_calls_;
63 int last_prefetch_count_; 72 int last_prefetch_count_;
73 int advance_calls_;
64 int continue_calls_; 74 int continue_calls_;
65 int32 destroyed_cursor_id_; 75 int32 destroyed_cursor_id_;
66 scoped_ptr<WebIDBCallbacks> callbacks_; 76 scoped_ptr<WebIDBCallbacks> callbacks_;
67 }; 77 };
68 78
69 class MockContinueCallbacks : public WebIDBCallbacks { 79 class MockContinueCallbacks : public WebIDBCallbacks {
70 public: 80 public:
71 MockContinueCallbacks(IndexedDBKey* key = 0) : key_(key) {} 81 MockContinueCallbacks(IndexedDBKey* key = 0) : key_(key) {}
72 82
73 virtual void onSuccess(const WebIDBKey& key, 83 virtual void onSuccess(const WebIDBKey& key,
74 const WebIDBKey& primaryKey, 84 const WebIDBKey& primaryKey,
75 const WebData& value) { 85 const WebData& value) {
76 86
77 if (key_) 87 if (key_)
78 *key_ = IndexedDBKeyBuilder::Build(key); 88 *key_ = IndexedDBKeyBuilder::Build(key);
79 } 89 }
80 90
81 private: 91 private:
82 IndexedDBKey* key_; 92 IndexedDBKey* key_;
83 }; 93 };
84 94
85 } // namespace 95 } // namespace
86 96
87 TEST(WebIDBCursorImplTest, PrefetchTest) { 97 class WebIDBCursorImplTest : public testing::Test {
98 public:
99 WebIDBCursorImplTest() {
100 null_key_.assignNull();
101 sync_message_filter_ = new IPC::SyncMessageFilter(NULL);
102 thread_safe_sender_ = new ThreadSafeSender(
103 base::MessageLoopProxy::current(), sync_message_filter_.get());
104 dispatcher_ =
105 make_scoped_ptr(new MockDispatcher(thread_safe_sender_.get()));
106 }
88 107
89 WebIDBKey null_key; 108 protected:
90 null_key.assignNull(); 109 WebIDBKey null_key_;
110 scoped_refptr<ThreadSafeSender> thread_safe_sender_;
111 scoped_ptr<MockDispatcher> dispatcher_;
91 112
92 scoped_refptr<base::MessageLoopProxy> message_loop_proxy( 113 private:
93 base::MessageLoopProxy::current()); 114 scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_;
94 scoped_refptr<IPC::SyncMessageFilter> sync_message_filter(
95 new IPC::SyncMessageFilter(NULL));
96 scoped_refptr<ThreadSafeSender> thread_safe_sender(new ThreadSafeSender(
97 message_loop_proxy.get(), sync_message_filter.get()));
98 115
99 MockDispatcher dispatcher(thread_safe_sender.get()); 116 DISALLOW_COPY_AND_ASSIGN(WebIDBCursorImplTest);
117 };
118
119 TEST_F(WebIDBCursorImplTest, PrefetchTest) {
100 120
101 { 121 {
102 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId, 122 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
103 thread_safe_sender.get()); 123 thread_safe_sender_.get());
104 124
105 // Call continue() until prefetching should kick in. 125 // Call continue() until prefetching should kick in.
106 int continue_calls = 0; 126 int continue_calls = 0;
107 EXPECT_EQ(dispatcher.continue_calls(), 0); 127 EXPECT_EQ(dispatcher_->continue_calls(), 0);
108 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) { 128 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
109 cursor.continueFunction(null_key, new MockContinueCallbacks()); 129 cursor.continueFunction(null_key_, new MockContinueCallbacks());
110 EXPECT_EQ(++continue_calls, dispatcher.continue_calls()); 130 EXPECT_EQ(++continue_calls, dispatcher_->continue_calls());
111 EXPECT_EQ(0, dispatcher.prefetch_calls()); 131 EXPECT_EQ(0, dispatcher_->prefetch_calls());
112 } 132 }
113 133
114 // Do enough repetitions to verify that the count grows each time, 134 // Do enough repetitions to verify that the count grows each time,
115 // but not so many that the maximum limit is hit. 135 // but not so many that the maximum limit is hit.
116 const int kPrefetchRepetitions = 5; 136 const int kPrefetchRepetitions = 5;
117 137
118 int expected_key = 0; 138 int expected_key = 0;
119 int last_prefetch_count = 0; 139 int last_prefetch_count = 0;
120 for (int repetitions = 0; repetitions < kPrefetchRepetitions; 140 for (int repetitions = 0; repetitions < kPrefetchRepetitions;
121 ++repetitions) { 141 ++repetitions) {
122 142
123 // Initiate the prefetch 143 // Initiate the prefetch
124 cursor.continueFunction(null_key, new MockContinueCallbacks()); 144 cursor.continueFunction(null_key_, new MockContinueCallbacks());
125 EXPECT_EQ(continue_calls, dispatcher.continue_calls()); 145 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
126 EXPECT_EQ(repetitions + 1, dispatcher.prefetch_calls()); 146 EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
127 147
128 // Verify that the requested count has increased since last time. 148 // Verify that the requested count has increased since last time.
129 int prefetch_count = dispatcher.last_prefetch_count(); 149 int prefetch_count = dispatcher_->last_prefetch_count();
130 EXPECT_GT(prefetch_count, last_prefetch_count); 150 EXPECT_GT(prefetch_count, last_prefetch_count);
131 last_prefetch_count = prefetch_count; 151 last_prefetch_count = prefetch_count;
132 152
133 // Fill the prefetch cache as requested. 153 // Fill the prefetch cache as requested.
134 std::vector<IndexedDBKey> keys; 154 std::vector<IndexedDBKey> keys;
135 std::vector<IndexedDBKey> primary_keys(prefetch_count); 155 std::vector<IndexedDBKey> primary_keys(prefetch_count);
136 std::vector<WebData> values(prefetch_count); 156 std::vector<WebData> values(prefetch_count);
137 for (int i = 0; i < prefetch_count; ++i) { 157 for (int i = 0; i < prefetch_count; ++i) {
138 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber)); 158 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
139 } 159 }
140 cursor.SetPrefetchData(keys, primary_keys, values); 160 cursor.SetPrefetchData(keys, primary_keys, values);
141 161
142 // Note that the real dispatcher would call cursor->CachedContinue() 162 // Note that the real dispatcher would call cursor->CachedContinue()
143 // immediately after cursor->SetPrefetchData() to service the request 163 // immediately after cursor->SetPrefetchData() to service the request
144 // that initiated the prefetch. 164 // that initiated the prefetch.
145 165
146 // Verify that the cache is used for subsequent continue() calls. 166 // Verify that the cache is used for subsequent continue() calls.
147 for (int i = 0; i < prefetch_count; ++i) { 167 for (int i = 0; i < prefetch_count; ++i) {
148 IndexedDBKey key; 168 IndexedDBKey key;
149 cursor.continueFunction(null_key, new MockContinueCallbacks(&key)); 169 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
150 EXPECT_EQ(continue_calls, dispatcher.continue_calls()); 170 EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
151 EXPECT_EQ(repetitions + 1, dispatcher.prefetch_calls()); 171 EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
152 172
153 EXPECT_EQ(WebIDBKeyTypeNumber, key.type()); 173 EXPECT_EQ(WebIDBKeyTypeNumber, key.type());
154 EXPECT_EQ(expected_key++, key.number()); 174 EXPECT_EQ(expected_key++, key.number());
155 } 175 }
156 } 176 }
157 } 177 }
158 178
159 EXPECT_EQ(dispatcher.destroyed_cursor_id(), 179 EXPECT_EQ(dispatcher_->destroyed_cursor_id(),
160 WebIDBCursorImpl::kInvalidCursorId); 180 WebIDBCursorImpl::kInvalidCursorId);
161 } 181 }
162 182
183 TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
184
185 WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId,
186 thread_safe_sender_.get());
187
188 // Call continue() until prefetching should kick in.
189 EXPECT_EQ(0, dispatcher_->continue_calls());
190 for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) {
191 cursor.continueFunction(null_key_, new MockContinueCallbacks());
192 }
193 EXPECT_EQ(0, dispatcher_->prefetch_calls());
194
195 // Initiate the prefetch
196 cursor.continueFunction(null_key_, new MockContinueCallbacks());
197
198 EXPECT_EQ(1, dispatcher_->prefetch_calls());
199 EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
200 dispatcher_->continue_calls());
201 EXPECT_EQ(0, dispatcher_->advance_calls());
202
203 const int prefetch_count = dispatcher_->last_prefetch_count();
204
205 // Fill the prefetch cache as requested.
206 int expected_key = 0;
207 std::vector<IndexedDBKey> keys;
208 std::vector<IndexedDBKey> primary_keys(prefetch_count);
209 std::vector<WebData> values(prefetch_count);
210 for (int i = 0; i < prefetch_count; ++i) {
211 keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
212 }
213 cursor.SetPrefetchData(keys, primary_keys, values);
214
215 // Note that the real dispatcher would call cursor->CachedContinue()
216 // immediately after cursor->SetPrefetchData() to service the request
217 // that initiated the prefetch.
218
219 // Need at least this many in the cache for the test steps.
220 ASSERT_GE(prefetch_count, 5);
221
222 // IDBCursor.continue()
223 IndexedDBKey key;
224 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
225 EXPECT_EQ(0, key.number());
226
227 // IDBCursor.advance(1)
228 cursor.advance(1, new MockContinueCallbacks(&key));
229 EXPECT_EQ(1, key.number());
230
231 // IDBCursor.continue()
232 cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
233 EXPECT_EQ(2, key.number());
234
235 // IDBCursor.advance(2)
236 cursor.advance(2, new MockContinueCallbacks(&key));
237 EXPECT_EQ(4, key.number());
238
239 EXPECT_EQ(0, dispatcher_->advance_calls());
240
241 // IDBCursor.advance(lots) - beyond the fetched amount
242 cursor.advance(WebIDBCursorImpl::kMaxPrefetchAmount,
243 new MockContinueCallbacks(&key));
244 EXPECT_EQ(1, dispatcher_->advance_calls());
245 EXPECT_EQ(1, dispatcher_->prefetch_calls());
246 EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold),
247 dispatcher_->continue_calls());
248 }
249
163 } // namespace content 250 } // namespace content
OLDNEW
« no previous file with comments | « content/child/indexed_db/webidbcursor_impl.cc ('k') | content/child/thread_safe_sender.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698