indexed_db_cursor.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_cursor.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/bind.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/indexed_db/indexed_db_callbacks.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_database_error.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_tracing.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_transaction.h" 1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_value.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBCursor::IndexedDBCursor( 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Cursor> cursor, 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::CursorType cursor_type, 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBDatabase::TaskType task_type, 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* transaction) 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : task_type_(task_type), 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_type_(cursor_type), 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_(transaction), 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_(cursor.Pass()), 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) closed_(false) { 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->RegisterOpenCursor(this); 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBCursor::~IndexedDBCursor() { 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->UnregisterOpenCursor(this); 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IndexedDBCursor::Continue(scoped_ptr<IndexedDBKey> key, 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key, 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBCursor::Continue"); 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->ScheduleTask( 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) task_type_, 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBCursor::CursorIterationOperation, 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Passed(&key), 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&primary_key), 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBCursor::Advance(uint32 count, 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBCursor::Advance"); 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->ScheduleTask( 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) task_type_, 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind( 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &IndexedDBCursor::CursorAdvanceOperation, this, count, callbacks)); 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBCursor::CursorAdvanceOperation( 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint32 count, 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* /*transaction*/) { 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation"); 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(cmumford): Handle this error (crbug.com/363397). Although this will 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // properly fail, caller will not know why, and any corruption 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // will be ignored. 670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!cursor_ || !cursor_->Advance(count, &s)) { 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cursor_.reset(); 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccess(key(), primary_key(), Value()); 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBCursor::CursorIterationOperation( 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<IndexedDBKey> key, 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<IndexedDBKey> primary_key, 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* /*transaction*/) { 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBCursor::CursorIterationOperation"); 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(cmumford): Handle this error (crbug.com/363397). Although this will 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // properly fail, caller will not know why, and any corruption 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // will be ignored. 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!cursor_ || !cursor_->Continue(key.get(), 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch primary_key.get(), 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IndexedDBBackingStore::Cursor::SEEK, 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &s) || !s.ok()) { 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cursor_.reset(); 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callbacks->OnSuccess(this->key(), this->primary_key(), Value()); 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBCursor::PrefetchContinue( 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int number_to_fetch, 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks) { 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBCursor::PrefetchContinue"); 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->ScheduleTask( 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) task_type_, 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&IndexedDBCursor::CursorPrefetchIterationOperation, 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_to_fetch, 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks)); 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void IndexedDBCursor::CursorPrefetchIterationOperation( 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int number_to_fetch, 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<IndexedDBCallbacks> callbacks, 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBTransaction* /*transaction*/) { 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDB_TRACE("IndexedDBCursor::CursorPrefetchIterationOperation"); 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<IndexedDBKey> found_keys; 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<IndexedDBKey> found_primary_keys; 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::vector<IndexedDBValue> found_values; 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_cursor_.reset(); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const size_t max_size_estimate = 10 * 1024 * 1024; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t size_estimate = 0; 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(cmumford): Handle this error (crbug.com/363397). Although this will 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // properly fail, caller will not know why, and any corruption 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // will be ignored. 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (int i = 0; i < number_to_fetch; ++i) { 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!cursor_ || !cursor_->Continue(&s)) { 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cursor_.reset(); 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i == 0) { 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First prefetched result is always used, so that's the position 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a cursor should be reset to if the prefetch is invalidated. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_cursor_.reset(cursor_->Clone()); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) found_keys.push_back(cursor_->key()); 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) found_primary_keys.push_back(cursor_->primary_key()); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (cursor_type_) { 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case indexed_db::CURSOR_KEY_ONLY: 14623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found_values.push_back(IndexedDBValue()); 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case indexed_db::CURSOR_KEY_AND_VALUE: { 14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IndexedDBValue value; 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value.swap(*cursor_->value()); 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_estimate += value.SizeEstimate(); 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) found_values.push_back(value); 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default: 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NOTREACHED(); 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_estimate += cursor_->key().size_estimate(); 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_estimate += cursor_->primary_key().size_estimate(); 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (size_estimate > max_size_estimate) 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!found_keys.size()) { 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callbacks->OnSuccessWithPrefetch( 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) found_keys, found_primary_keys, found_values); 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status IndexedDBCursor::PrefetchReset(int used_prefetches, 1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int /* unused_prefetches */) { 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBCursor::PrefetchReset"); 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_.swap(saved_cursor_); 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) saved_cursor_.reset(); 1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (closed_) 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (cursor_) { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First prefetched result is always used. 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_GT(used_prefetches, 0); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < used_prefetches - 1; ++i) { 1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool ok = cursor_->Continue(&s); 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(ok); 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBCursor::Close() { 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBCursor::Close"); 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) closed_ = true; 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cursor_.reset(); 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) saved_cursor_.reset(); 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 203