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/leveldb/leveldb_transaction.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_database.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/db.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::StringPiece; 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace content { 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db) 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : db_(db), 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) snapshot_(db), 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) comparator_(db->Comparator()), 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_comparator_(comparator_), 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_(data_comparator_), 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) finished_(false) {} 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LevelDBTransaction::Record::Record() : deleted(false) {} 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LevelDBTransaction::Record::~Record() {} 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void LevelDBTransaction::Clear() { 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (DataType::iterator it = data_.begin(); it != data_.end(); ++it) { 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delete it->second; 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_.clear(); 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LevelDBTransaction::~LevelDBTransaction() { Clear(); } 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid LevelDBTransaction::Set(const StringPiece& key, 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string* value, 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool deleted) { 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!finished_); 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType::iterator it = data_.find(key); 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (it == data_.end()) { 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Record* record = new Record(); 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) record->key.assign(key.begin(), key.end() - key.begin()); 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) record->value.swap(*value); 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) record->deleted = deleted; 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_[record->key] = record; 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NotifyIterators(); 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) it->second->value.swap(*value); 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) it->second->deleted = deleted; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid LevelDBTransaction::Put(const StringPiece& key, std::string* value) { 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Set(key, value, false); 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid LevelDBTransaction::Remove(const StringPiece& key) { 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string empty; 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Set(key, &empty, true); 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status LevelDBTransaction::Get(const StringPiece& key, 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* value, 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool* found) { 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *found = false; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!finished_); 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string string_key(key.begin(), key.end() - key.begin()); 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType::const_iterator it = data_.find(string_key); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (it != data_.end()) { 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (it->second->deleted) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return leveldb::Status::OK(); 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *value = it->second->value; 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *found = true; 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return leveldb::Status::OK(); 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = db_->Get(key, value, found, &snapshot_); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!*found); 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status LevelDBTransaction::Commit() { 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!finished_); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_.empty()) { 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) finished_ = true; 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return leveldb::Status::OK(); 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create(); 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (DataType::iterator iterator = data_.begin(); iterator != data_.end(); 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ++iterator) { 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!iterator->second->deleted) 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) write_batch->Put(iterator->first, iterator->second->value); 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) write_batch->Remove(iterator->first); 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = db_->Write(*write_batch); 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (s.ok()) { 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Clear(); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) finished_ = true; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LevelDBTransaction::Rollback() { 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!finished_); 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) finished_ = true; 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Clear(); 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<LevelDBIterator> LevelDBTransaction::CreateIterator() { 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return TransactionIterator::Create(this).PassAs<LevelDBIterator>(); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)scoped_ptr<LevelDBTransaction::DataIterator> 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) { 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return make_scoped_ptr(new DataIterator(transaction)); 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool LevelDBTransaction::DataIterator::IsValid() const { 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return iterator_ != data_->end(); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::DataIterator::SeekToLast() { 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) iterator_ = data_->end(); 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (iterator_ != data_->begin()) 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --iterator_; 1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return leveldb::Status::OK(); 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::DataIterator::Seek( 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const StringPiece& target) { 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) iterator_ = data_->lower_bound(target); 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return leveldb::Status::OK(); 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::DataIterator::Next() { 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++iterator_; 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return leveldb::Status::OK(); 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::DataIterator::Prev() { 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (iterator_ != data_->begin()) 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --iterator_; 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) iterator_ = data_->end(); 1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return leveldb::Status::OK(); 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)StringPiece LevelDBTransaction::DataIterator::Key() const { 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return iterator_->first; 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)StringPiece LevelDBTransaction::DataIterator::Value() const { 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!IsDeleted()); 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return iterator_->second->value; 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool LevelDBTransaction::DataIterator::IsDeleted() const { 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return iterator_->second->deleted; 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LevelDBTransaction::DataIterator::~DataIterator() {} 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LevelDBTransaction::DataIterator::DataIterator(LevelDBTransaction* transaction) 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : data_(&transaction->data_), 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) iterator_(data_->end()) {} 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<LevelDBTransaction::TransactionIterator> 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)LevelDBTransaction::TransactionIterator::Create( 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<LevelDBTransaction> transaction) { 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return make_scoped_ptr(new TransactionIterator(transaction)); 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)LevelDBTransaction::TransactionIterator::TransactionIterator( 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<LevelDBTransaction> transaction) 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : transaction_(transaction), 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) comparator_(transaction_->comparator_), 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_(DataIterator::Create(transaction_.get())), 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_iterator_(transaction_->db_->CreateIterator(&transaction_->snapshot_)), 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_(0), 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_(FORWARD), 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_changed_(false) { 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->RegisterIterator(this); 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)LevelDBTransaction::TransactionIterator::~TransactionIterator() { 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) transaction_->UnregisterIterator(this); 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool LevelDBTransaction::TransactionIterator::IsValid() const { 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !!current_; 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::TransactionIterator::SeekToLast() { 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s = data_iterator_->SeekToLast(); 2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(s.ok()); 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch s = db_iterator_->SeekToLast(); 2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_ = REVERSE; 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HandleConflictsAndDeletes(); 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetCurrentIteratorToLargestKey(); 2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::TransactionIterator::Seek( 2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const StringPiece& target) { 2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s = data_iterator_->Seek(target); 2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(s.ok()); 2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch s = db_iterator_->Seek(target); 2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_ = FORWARD; 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HandleConflictsAndDeletes(); 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetCurrentIteratorToSmallestKey(); 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::TransactionIterator::Next() { 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_changed_) 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RefreshDataIterator(); 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (direction_ != FORWARD) { 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Ensure the non-current iterator is positioned after Key(). 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LevelDBIterator* non_current = (current_ == db_iterator_.get()) 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ? data_iterator_.get() 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : db_iterator_.get(); 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) non_current->Seek(Key()); 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (non_current->IsValid() && 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) !comparator_->Compare(non_current->Key(), Key())) { 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Take an extra step so the non-current key is 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // strictly greater than Key(). 2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch s = non_current->Next(); 2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) 2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!non_current->IsValid() || 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) comparator_->Compare(non_current->Key(), Key()) > 0); 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_ = FORWARD; 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch s = current_->Next(); 2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) 2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HandleConflictsAndDeletes(); 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetCurrentIteratorToSmallestKey(); 2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return leveldb::Status::OK(); 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochleveldb::Status LevelDBTransaction::TransactionIterator::Prev() { 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch leveldb::Status s; 275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_changed_) 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RefreshDataIterator(); 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (direction_ != REVERSE) { 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Ensure the non-current iterator is positioned before Key(). 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LevelDBIterator* non_current = (current_ == db_iterator_.get()) 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ? data_iterator_.get() 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : db_iterator_.get(); 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch s = non_current->Seek(Key()); 2860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) 2870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (non_current->IsValid()) { 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Iterator is at first entry >= Key(). 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Step back once to entry < key. 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This is why we don't check for the keys being the same before 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // stepping, like we do in Next() above. 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) non_current->Prev(); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Iterator has no entries >= Key(). Position at last entry. 296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) non_current->SeekToLast(); 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!non_current->IsValid() || 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) comparator_->Compare(non_current->Key(), Key()) < 0); 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) direction_ = REVERSE; 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch s = current_->Prev(); 3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!s.ok()) 3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return s; 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HandleConflictsAndDeletes(); 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetCurrentIteratorToLargestKey(); 3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return leveldb::Status::OK(); 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochStringPiece LevelDBTransaction::TransactionIterator::Key() const { 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_changed_) 315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RefreshDataIterator(); 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return current_->Key(); 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochStringPiece LevelDBTransaction::TransactionIterator::Value() const { 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(IsValid()); 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_changed_) 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RefreshDataIterator(); 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return current_->Value(); 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void LevelDBTransaction::TransactionIterator::DataChanged() { 327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_changed_ = true; 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void LevelDBTransaction::TransactionIterator::RefreshDataIterator() const { 331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(data_changed_); 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_changed_ = false; 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid() && data_iterator_.get() == current_) { 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (db_iterator_->IsValid()) { 340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // There could be new records in data that we should iterate over. 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (direction_ == FORWARD) { 343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Try to seek data iterator to something greater than the db iterator. 344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_->Seek(db_iterator_->Key()); 345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid() && 346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) !comparator_->Compare(data_iterator_->Key(), db_iterator_->Key())) { 347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If equal, take another step so the data iterator is strictly greater. 348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_->Next(); 349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If going backward, seek to a key less than the db iterator. 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(REVERSE, direction_); 353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_->Seek(db_iterator_->Key()); 354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid()) 355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_->Prev(); 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 360d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool LevelDBTransaction::TransactionIterator::DataIteratorIsLower() const { 361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) < 0; 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool LevelDBTransaction::TransactionIterator::DataIteratorIsHigher() const { 365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) > 0; 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() { 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool loop = true; 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while (loop) { 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loop = false; 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid() && db_iterator_->IsValid() && 375d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) !comparator_->Compare(data_iterator_->Key(), db_iterator_->Key())) { 376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // For equal keys, the data iterator takes precedence, so move the 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // database iterator another step. 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (direction_ == FORWARD) 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_iterator_->Next(); 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_iterator_->Prev(); 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 384d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Skip over delete markers in the data iterator until it catches up with 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the db iterator. 386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid() && data_iterator_->IsDeleted()) { 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (direction_ == FORWARD && 388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) (!db_iterator_->IsValid() || DataIteratorIsLower())) { 389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_->Next(); 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loop = true; 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (direction_ == REVERSE && 392d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) (!db_iterator_->IsValid() || DataIteratorIsHigher())) { 393d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_iterator_->Prev(); 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loop = true; 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() { 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBIterator* smallest = 0; 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid()) 405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) smallest = data_iterator_.get(); 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (db_iterator_->IsValid()) { 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!smallest || 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) comparator_->Compare(db_iterator_->Key(), smallest->Key()) < 0) 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) smallest = db_iterator_.get(); 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ = smallest; 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LevelDBTransaction::TransactionIterator::SetCurrentIteratorToLargestKey() { 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBIterator* largest = 0; 418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 419d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (data_iterator_->IsValid()) 420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) largest = data_iterator_.get(); 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (db_iterator_->IsValid()) { 423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!largest || 424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) comparator_->Compare(db_iterator_->Key(), largest->Key()) > 0) 425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) largest = db_iterator_.get(); 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ = largest; 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) { 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(iterators_.find(iterator) == iterators_.end()); 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iterators_.insert(iterator); 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) { 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(iterators_.find(iterator) != iterators_.end()); 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iterators_.erase(iterator); 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void LevelDBTransaction::NotifyIterators() { 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (std::set<TransactionIterator*>::iterator i = iterators_.begin(); 443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) i != iterators_.end(); 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++i) { 445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TransactionIterator* transaction_iterator = *i; 446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_iterator->DataChanged(); 447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<LevelDBDirectTransaction> LevelDBDirectTransaction::Create( 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBDatabase* db) { 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return make_scoped_ptr(new LevelDBDirectTransaction(db)); 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)LevelDBDirectTransaction::LevelDBDirectTransaction(LevelDBDatabase* db) 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {} 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)LevelDBDirectTransaction::~LevelDBDirectTransaction() { 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) write_batch_->Clear(); 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void LevelDBDirectTransaction::Put(const StringPiece& key, 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string* value) { 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!finished_); 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_batch_->Put(key, *value); 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status LevelDBDirectTransaction::Get(const StringPiece& key, 469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* value, 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool* found) { 471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *found = false; 472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!finished_); 473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = db_->Get(key, value, found); 475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(s.ok() || !*found); 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void LevelDBDirectTransaction::Remove(const StringPiece& key) { 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!finished_); 481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_batch_->Remove(key); 482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)leveldb::Status LevelDBDirectTransaction::Commit() { 485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!finished_); 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = db_->Write(*write_batch_); 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (s.ok()) { 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) finished_ = true; 490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_batch_->Clear(); 491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return s; 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 496