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