15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/values.h" 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/child/indexed_db/indexed_db_dispatcher.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/child/indexed_db/indexed_db_key_builders.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/child/indexed_db/webidbcursor_impl.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/child/thread_safe_sender.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebData.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebIDBCallbacks.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing blink::WebBlobInfo; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebData; 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebIDBCallbacks; 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebIDBDatabase; 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebIDBKey; 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using blink::WebIDBKeyTypeNumber; 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing blink::WebVector; 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockDispatcher : public IndexedDBDispatcher { 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit MockDispatcher(ThreadSafeSender* thread_safe_sender) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : IndexedDBDispatcher(thread_safe_sender), 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefetch_calls_(0), 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_prefetch_count_(0), 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reset_calls_(0), 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_used_count_(0), 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) advance_calls_(0), 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue_calls_(0), 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destroyed_cursor_id_(0) {} 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void RequestIDBCursorPrefetch(int n, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCallbacks* callbacks, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 ipc_cursor_id) OVERRIDE { 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++prefetch_calls_; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_prefetch_count_ = n; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks_.reset(callbacks); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void RequestIDBCursorPrefetchReset(int used_prefetches, 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int unused_prefetches, 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 ipc_cursor_id) OVERRIDE { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++reset_calls_; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_used_count_ = used_prefetches; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void RequestIDBCursorAdvance(unsigned long count, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCallbacks* callbacks, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 ipc_cursor_id, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 transaction_id) OVERRIDE { 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++advance_calls_; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks_.reset(callbacks); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void RequestIDBCursorContinue(const IndexedDBKey& key, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const IndexedDBKey& primary_key, 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCallbacks* callbacks, 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 ipc_cursor_id, 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 transaction_id) OVERRIDE { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++continue_calls_; 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callbacks_.reset(callbacks); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void CursorDestroyed(int32 ipc_cursor_id) OVERRIDE { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destroyed_cursor_id_ = ipc_cursor_id; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int prefetch_calls() { return prefetch_calls_; } 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int last_prefetch_count() { return last_prefetch_count_; } 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int reset_calls() { return reset_calls_; } 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int last_used_count() { return last_used_count_; } 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int advance_calls() { return advance_calls_; } 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int continue_calls() { return continue_calls_; } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 destroyed_cursor_id() { return destroyed_cursor_id_; } 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int prefetch_calls_; 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int last_prefetch_count_; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int reset_calls_; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int last_used_count_; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int advance_calls_; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int continue_calls_; 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 destroyed_cursor_id_; 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebIDBCallbacks> callbacks_; 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockContinueCallbacks : public WebIDBCallbacks { 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MockContinueCallbacks(IndexedDBKey* key = 0, 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WebVector<WebBlobInfo>* webBlobInfo = 0) 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : key_(key), webBlobInfo_(webBlobInfo) {} 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void onSuccess(const WebIDBKey& key, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const WebIDBKey& primaryKey, 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const WebData& value, 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const WebVector<WebBlobInfo>& webBlobInfo) OVERRIDE { 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (key_) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *key_ = IndexedDBKeyBuilder::Build(key); 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (webBlobInfo_) 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *webBlobInfo_ = webBlobInfo; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBKey* key_; 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WebVector<WebBlobInfo>* webBlobInfo_; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class WebIDBCursorImplTest : public testing::Test { 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCursorImplTest() { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) null_key_.assignNull(); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_message_filter_ = new IPC::SyncMessageFilter(NULL); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thread_safe_sender_ = new ThreadSafeSender( 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoopProxy::current(), sync_message_filter_.get()); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_ = 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) make_scoped_ptr(new MockDispatcher(thread_safe_sender_.get())); 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBKey null_key_; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<ThreadSafeSender> thread_safe_sender_; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<MockDispatcher> dispatcher_; 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WebIDBCursorImplTest); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WebIDBCursorImplTest, PrefetchTest) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int64 transaction_id = 1; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId, 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_id, 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thread_safe_sender_.get()); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call continue() until prefetching should kick in. 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int continue_calls = 0; 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(dispatcher_->continue_calls(), 0); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) { 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks()); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(++continue_calls, dispatcher_->continue_calls()); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->prefetch_calls()); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Do enough repetitions to verify that the count grows each time, 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // but not so many that the maximum limit is hit. 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int kPrefetchRepetitions = 5; 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int expected_key = 0; 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int last_prefetch_count = 0; 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int repetitions = 0; repetitions < kPrefetchRepetitions; 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++repetitions) { 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Initiate the prefetch 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks()); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(continue_calls, dispatcher_->continue_calls()); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls()); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify that the requested count has increased since last time. 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int prefetch_count = dispatcher_->last_prefetch_count(); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_GT(prefetch_count, last_prefetch_count); 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_prefetch_count = prefetch_count; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Fill the prefetch cache as requested. 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<IndexedDBKey> keys; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<IndexedDBKey> primary_keys(prefetch_count); 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<WebData> values(prefetch_count); 1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<WebVector<WebBlobInfo> > blob_info; 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < prefetch_count; ++i) { 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber)); 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blob_info.push_back( 1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i))); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu cursor.SetPrefetchData(keys, primary_keys, values, blob_info); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that the real dispatcher would call cursor->CachedContinue() 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // immediately after cursor->SetPrefetchData() to service the request 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // that initiated the prefetch. 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify that the cache is used for subsequent continue() calls. 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < prefetch_count; ++i) { 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBKey key; 1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WebVector<WebBlobInfo> web_blob_info; 1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu cursor.continueFunction( 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu null_key_, new MockContinueCallbacks(&key, &web_blob_info)); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(continue_calls, dispatcher_->continue_calls()); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls()); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(WebIDBKeyTypeNumber, key.type()); 2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(expected_key, static_cast<int>(web_blob_info.size())); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(expected_key++, key.number()); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(dispatcher_->destroyed_cursor_id(), 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCursorImpl::kInvalidCursorId); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) { 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int64 transaction_id = 1; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId, 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_id, 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thread_safe_sender_.get()); 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call continue() until prefetching should kick in. 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->continue_calls()); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) { 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks()); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->prefetch_calls()); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Initiate the prefetch 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks()); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, dispatcher_->prefetch_calls()); 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold), 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_->continue_calls()); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->advance_calls()); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int prefetch_count = dispatcher_->last_prefetch_count(); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Fill the prefetch cache as requested. 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int expected_key = 0; 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<IndexedDBKey> keys; 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<IndexedDBKey> primary_keys(prefetch_count); 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<WebData> values(prefetch_count); 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<WebVector<WebBlobInfo> > blob_info; 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < prefetch_count; ++i) { 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber)); 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu blob_info.push_back( 2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i))); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu cursor.SetPrefetchData(keys, primary_keys, values, blob_info); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that the real dispatcher would call cursor->CachedContinue() 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // immediately after cursor->SetPrefetchData() to service the request 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // that initiated the prefetch. 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Need at least this many in the cache for the test steps. 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_GE(prefetch_count, 5); 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IDBCursor.continue() 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBKey key; 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks(&key)); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, key.number()); 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IDBCursor.advance(1) 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.advance(1, new MockContinueCallbacks(&key)); 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, key.number()); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IDBCursor.continue() 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks(&key)); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(2, key.number()); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IDBCursor.advance(2) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.advance(2, new MockContinueCallbacks(&key)); 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(4, key.number()); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->advance_calls()); 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IDBCursor.advance(lots) - beyond the fetched amount 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.advance(WebIDBCursorImpl::kMaxPrefetchAmount, 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new MockContinueCallbacks(&key)); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, dispatcher_->advance_calls()); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, dispatcher_->prefetch_calls()); 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(static_cast<int>(WebIDBCursorImpl::kPrefetchContinueThreshold), 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_->continue_calls()); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WebIDBCursorImplTest, PrefetchReset) { 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int64 transaction_id = 1; 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebIDBCursorImpl cursor(WebIDBCursorImpl::kInvalidCursorId, 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction_id, 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thread_safe_sender_.get()); 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call continue() until prefetching should kick in. 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int continue_calls = 0; 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(dispatcher_->continue_calls(), 0); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < WebIDBCursorImpl::kPrefetchContinueThreshold; ++i) { 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks()); 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(++continue_calls, dispatcher_->continue_calls()); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->prefetch_calls()); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Initiate the prefetch 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.continueFunction(null_key_, new MockContinueCallbacks()); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(continue_calls, dispatcher_->continue_calls()); 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, dispatcher_->prefetch_calls()); 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->reset_calls()); 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now invalidate it 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.ResetPrefetchCache(); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No reset should have been sent since nothing has been received yet. 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->reset_calls()); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Fill the prefetch cache as requested. 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int prefetch_count = dispatcher_->last_prefetch_count(); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<IndexedDBKey> keys(prefetch_count); 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<IndexedDBKey> primary_keys(prefetch_count); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<WebData> values(prefetch_count); 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<WebVector<WebBlobInfo> > blob_info(prefetch_count); 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu cursor.SetPrefetchData(keys, primary_keys, values, blob_info); 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No reset should have been sent since prefetch data hasn't been used. 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, dispatcher_->reset_calls()); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The real dispatcher would call cursor->CachedContinue(), so do that: 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WebIDBCallbacks> callbacks(new MockContinueCallbacks()); 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor.CachedContinue(callbacks.get()); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now the cursor should have reset the rest of the cache. 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, dispatcher_->reset_calls()); 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(1, dispatcher_->last_used_count()); 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 330