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

Side by Side Diff: content/browser/indexed_db/leveldb/leveldb_transaction.cc

Issue 17462005: IndexedDB: Replace transaction's AVLTree with std::map (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove iterator validation support Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 5 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 8 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" 9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h"
10 #include "third_party/leveldatabase/src/include/leveldb/db.h" 10 #include "third_party/leveldatabase/src/include/leveldb/db.h"
11 11
12 using base::StringPiece; 12 using base::StringPiece;
13 13
14 namespace content { 14 namespace content {
15 15
16 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db) 16 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db)
17 : db_(db), snapshot_(db), comparator_(db->Comparator()), finished_(false) { 17 : db_(db),
18 tree_.abstractor().comparator_ = comparator_; 18 snapshot_(db),
19 comparator_(db->Comparator()),
20 data_comparator_(comparator_),
21 data_(data_comparator_),
22 finished_(false) {}
23
24 LevelDBTransaction::Record::Record() : deleted(false) {}
25 LevelDBTransaction::Record::~Record() {}
26
27 void LevelDBTransaction::Clear() {
28 for (DataType::iterator it = data_.begin(); it != data_.end(); ++it) {
29 delete it->second;
30 }
31 data_.clear();
19 } 32 }
20 33
21 LevelDBTransaction::AVLTreeNode::AVLTreeNode() {} 34 LevelDBTransaction::~LevelDBTransaction() { Clear(); }
22 LevelDBTransaction::AVLTreeNode::~AVLTreeNode() {}
23
24 void LevelDBTransaction::ClearTree() {
25 TreeType::Iterator iterator;
26 iterator.StartIterLeast(&tree_);
27
28 std::vector<AVLTreeNode*> nodes;
29
30 while (*iterator) {
31 nodes.push_back(*iterator);
32 ++iterator;
33 }
34 tree_.Purge();
35
36 for (size_t i = 0; i < nodes.size(); ++i)
37 delete nodes[i];
38 }
39
40 LevelDBTransaction::~LevelDBTransaction() { ClearTree(); }
41 35
42 void LevelDBTransaction::Set(const StringPiece& key, 36 void LevelDBTransaction::Set(const StringPiece& key,
43 std::string* value, 37 std::string* value,
44 bool deleted) { 38 bool deleted) {
45 DCHECK(!finished_); 39 DCHECK(!finished_);
46 bool new_node = false; 40 DataType::iterator it = data_.find(key);
47 AVLTreeNode* node = tree_.Search(key);
48 41
49 if (!node) { 42 if (it == data_.end()) {
50 node = new AVLTreeNode; 43 Record* record = new Record();
51 node->key = key.as_string(); 44 record->key.assign(key.begin(), key.end() - key.begin());
52 tree_.Insert(node); 45 record->value.swap(*value);
53 new_node = true; 46 record->deleted = deleted;
47 data_[record->key] = record;
48 NotifyIterators();
49 return;
54 } 50 }
55 node->value.swap(*value);
56 node->deleted = deleted;
57 51
58 if (new_node) 52 it->second->value.swap(*value);
59 NotifyIteratorsOfTreeChange(); 53 it->second->deleted = deleted;
60 } 54 }
61 55
62 void LevelDBTransaction::Put(const StringPiece& key, std::string* value) { 56 void LevelDBTransaction::Put(const StringPiece& key, std::string* value) {
63 Set(key, value, false); 57 Set(key, value, false);
64 } 58 }
65 59
66 void LevelDBTransaction::Remove(const StringPiece& key) { 60 void LevelDBTransaction::Remove(const StringPiece& key) {
67 std::string empty; 61 std::string empty;
68 Set(key, &empty, true); 62 Set(key, &empty, true);
69 } 63 }
70 64
71 bool LevelDBTransaction::Get(const StringPiece& key, 65 bool LevelDBTransaction::Get(const StringPiece& key,
72 std::string* value, 66 std::string* value,
73 bool* found) { 67 bool* found) {
74 *found = false; 68 *found = false;
75 DCHECK(!finished_); 69 DCHECK(!finished_);
76 AVLTreeNode* node = tree_.Search(key); 70 std::string string_key(key.begin(), key.end() - key.begin());
71 DataType::const_iterator it = data_.find(string_key);
77 72
78 if (node) { 73 if (it != data_.end()) {
79 if (node->deleted) 74 if (it->second->deleted)
80 return true; 75 return true;
81 76
82 *value = node->value; 77 *value = it->second->value;
83 *found = true; 78 *found = true;
84 return true; 79 return true;
85 } 80 }
86 81
87 bool ok = db_->Get(key, value, found, &snapshot_); 82 bool ok = db_->Get(key, value, found, &snapshot_);
88 if (!ok) { 83 if (!ok) {
89 DCHECK(!*found); 84 DCHECK(!*found);
90 return false; 85 return false;
91 } 86 }
92 return true; 87 return true;
93 } 88 }
94 89
95 bool LevelDBTransaction::Commit() { 90 bool LevelDBTransaction::Commit() {
96 DCHECK(!finished_); 91 DCHECK(!finished_);
97 92
98 if (tree_.IsEmpty()) { 93 if (data_.empty()) {
99 finished_ = true; 94 finished_ = true;
100 return true; 95 return true;
101 } 96 }
102 97
103 scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create(); 98 scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create();
104 99
105 TreeType::Iterator iterator; 100 for (DataType::iterator iterator = data_.begin(); iterator != data_.end();
106 iterator.StartIterLeast(&tree_); 101 ++iterator) {
107 102 if (!iterator->second->deleted)
108 while (*iterator) { 103 write_batch->Put(iterator->first, iterator->second->value);
109 AVLTreeNode* node = *iterator;
110 if (!node->deleted)
111 write_batch->Put(node->key, node->value);
112 else 104 else
113 write_batch->Remove(node->key); 105 write_batch->Remove(iterator->first);
114 ++iterator;
115 } 106 }
116 107
117 if (!db_->Write(*write_batch)) 108 if (!db_->Write(*write_batch))
118 return false; 109 return false;
119 110
120 ClearTree(); 111 Clear();
121 finished_ = true; 112 finished_ = true;
122 return true; 113 return true;
123 } 114 }
124 115
125 void LevelDBTransaction::Rollback() { 116 void LevelDBTransaction::Rollback() {
126 DCHECK(!finished_); 117 DCHECK(!finished_);
127 finished_ = true; 118 finished_ = true;
128 ClearTree(); 119 Clear();
129 } 120 }
130 121
131 scoped_ptr<LevelDBIterator> LevelDBTransaction::CreateIterator() { 122 scoped_ptr<LevelDBIterator> LevelDBTransaction::CreateIterator() {
132 return TransactionIterator::Create(this).PassAs<LevelDBIterator>(); 123 return TransactionIterator::Create(this).PassAs<LevelDBIterator>();
133 } 124 }
134 125
135 scoped_ptr<LevelDBTransaction::TreeIterator> 126 scoped_ptr<LevelDBTransaction::DataIterator>
136 LevelDBTransaction::TreeIterator::Create(LevelDBTransaction* transaction) { 127 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) {
137 return make_scoped_ptr(new TreeIterator(transaction)); 128 return make_scoped_ptr(new DataIterator(transaction));
138 } 129 }
139 130
140 bool LevelDBTransaction::TreeIterator::IsValid() const { return !!*iterator_; } 131 bool LevelDBTransaction::DataIterator::IsValid() const {
141 132 return iterator_ != data_->end();
142 void LevelDBTransaction::TreeIterator::SeekToLast() {
143 iterator_.StartIterGreatest(tree_);
144 if (IsValid())
145 key_ = (*iterator_)->key;
146 } 133 }
147 134
148 void LevelDBTransaction::TreeIterator::Seek(const StringPiece& target) { 135 void LevelDBTransaction::DataIterator::SeekToLast() {
149 iterator_.StartIter(tree_, target, TreeType::EQUAL); 136 iterator_ = data_->end();
150 if (!IsValid()) 137 if (iterator_ != data_->begin())
151 iterator_.StartIter(tree_, target, TreeType::GREATER); 138 --iterator_;
152
153 if (IsValid())
154 key_ = (*iterator_)->key;
155 } 139 }
156 140
157 void LevelDBTransaction::TreeIterator::Next() { 141 void LevelDBTransaction::DataIterator::Seek(const StringPiece& target) {
142 iterator_ = data_->lower_bound(target);
143 }
144
145 void LevelDBTransaction::DataIterator::Next() {
158 DCHECK(IsValid()); 146 DCHECK(IsValid());
159 ++iterator_; 147 ++iterator_;
160 if (IsValid()) {
161 DCHECK_GE(transaction_->comparator_->Compare((*iterator_)->key, key_), 0);
162 key_ = (*iterator_)->key;
163 }
164 } 148 }
165 149
166 void LevelDBTransaction::TreeIterator::Prev() { 150 void LevelDBTransaction::DataIterator::Prev() {
167 DCHECK(IsValid()); 151 DCHECK(IsValid());
168 --iterator_; 152 if (iterator_ != data_->begin())
169 if (IsValid()) { 153 --iterator_;
170 DCHECK_LT(tree_->abstractor().comparator_->Compare((*iterator_)->key, key_), 154 else
171 0); 155 iterator_ = data_->end();
172 key_ = (*iterator_)->key;
173 }
174 } 156 }
175 157
176 StringPiece LevelDBTransaction::TreeIterator::Key() const { 158 StringPiece LevelDBTransaction::DataIterator::Key() const {
177 DCHECK(IsValid()); 159 DCHECK(IsValid());
178 return key_; 160 return iterator_->first;
179 } 161 }
180 162
181 StringPiece LevelDBTransaction::TreeIterator::Value() const { 163 StringPiece LevelDBTransaction::DataIterator::Value() const {
182 DCHECK(IsValid()); 164 DCHECK(IsValid());
183 DCHECK(!IsDeleted()); 165 DCHECK(!IsDeleted());
184 return (*iterator_)->value; 166 return iterator_->second->value;
185 } 167 }
186 168
187 bool LevelDBTransaction::TreeIterator::IsDeleted() const { 169 bool LevelDBTransaction::DataIterator::IsDeleted() const {
188 DCHECK(IsValid()); 170 DCHECK(IsValid());
189 return (*iterator_)->deleted; 171 return iterator_->second->deleted;
190 } 172 }
191 173
192 void LevelDBTransaction::TreeIterator::Reset() { 174 LevelDBTransaction::DataIterator::~DataIterator() {}
193 DCHECK(IsValid());
194 iterator_.StartIter(tree_, key_, TreeType::EQUAL);
195 DCHECK(IsValid());
196 }
197 175
198 LevelDBTransaction::TreeIterator::~TreeIterator() {} 176 LevelDBTransaction::DataIterator::DataIterator(LevelDBTransaction* transaction)
199 177 : data_(&transaction->data_),
200 LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction) 178 iterator_(data_->end()) {}
201 : tree_(&transaction->tree_), transaction_(transaction) {}
202 179
203 scoped_ptr<LevelDBTransaction::TransactionIterator> 180 scoped_ptr<LevelDBTransaction::TransactionIterator>
204 LevelDBTransaction::TransactionIterator::Create( 181 LevelDBTransaction::TransactionIterator::Create(
205 scoped_refptr<LevelDBTransaction> transaction) { 182 scoped_refptr<LevelDBTransaction> transaction) {
206 return make_scoped_ptr(new TransactionIterator(transaction)); 183 return make_scoped_ptr(new TransactionIterator(transaction));
207 } 184 }
208 185
209 LevelDBTransaction::TransactionIterator::TransactionIterator( 186 LevelDBTransaction::TransactionIterator::TransactionIterator(
210 scoped_refptr<LevelDBTransaction> transaction) 187 scoped_refptr<LevelDBTransaction> transaction)
211 : transaction_(transaction), 188 : transaction_(transaction),
212 comparator_(transaction_->comparator_), 189 comparator_(transaction_->comparator_),
213 tree_iterator_(TreeIterator::Create(transaction_.get())), 190 data_iterator_(DataIterator::Create(transaction_.get())),
214 db_iterator_(transaction_->db_->CreateIterator(&transaction_->snapshot_)), 191 db_iterator_(transaction_->db_->CreateIterator(&transaction_->snapshot_)),
215 current_(0), 192 current_(0),
216 direction_(FORWARD), 193 direction_(FORWARD),
217 tree_changed_(false) { 194 data_changed_(false) {
218 transaction_->RegisterIterator(this); 195 transaction_->RegisterIterator(this);
219 } 196 }
220 197
221 LevelDBTransaction::TransactionIterator::~TransactionIterator() { 198 LevelDBTransaction::TransactionIterator::~TransactionIterator() {
222 transaction_->UnregisterIterator(this); 199 transaction_->UnregisterIterator(this);
223 } 200 }
224 201
225 bool LevelDBTransaction::TransactionIterator::IsValid() const { 202 bool LevelDBTransaction::TransactionIterator::IsValid() const {
226 return !!current_; 203 return !!current_;
227 } 204 }
228 205
229 void LevelDBTransaction::TransactionIterator::SeekToLast() { 206 void LevelDBTransaction::TransactionIterator::SeekToLast() {
230 tree_iterator_->SeekToLast(); 207 data_iterator_->SeekToLast();
231 db_iterator_->SeekToLast(); 208 db_iterator_->SeekToLast();
232 direction_ = REVERSE; 209 direction_ = REVERSE;
233 210
234 HandleConflictsAndDeletes(); 211 HandleConflictsAndDeletes();
235 SetCurrentIteratorToLargestKey(); 212 SetCurrentIteratorToLargestKey();
236 } 213 }
237 214
238 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { 215 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) {
239 tree_iterator_->Seek(target); 216 data_iterator_->Seek(target);
240 db_iterator_->Seek(target); 217 db_iterator_->Seek(target);
241 direction_ = FORWARD; 218 direction_ = FORWARD;
242 219
243 HandleConflictsAndDeletes(); 220 HandleConflictsAndDeletes();
244 SetCurrentIteratorToSmallestKey(); 221 SetCurrentIteratorToSmallestKey();
245 } 222 }
246 223
247 void LevelDBTransaction::TransactionIterator::Next() { 224 void LevelDBTransaction::TransactionIterator::Next() {
248 DCHECK(IsValid()); 225 DCHECK(IsValid());
249 if (tree_changed_) 226 if (data_changed_)
250 RefreshTreeIterator(); 227 RefreshDataIterator();
251 228
252 if (direction_ != FORWARD) { 229 if (direction_ != FORWARD) {
253 // Ensure the non-current iterator is positioned after Key(). 230 // Ensure the non-current iterator is positioned after Key().
254 231
255 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 232 LevelDBIterator* non_current = (current_ == db_iterator_.get())
256 ? tree_iterator_.get() 233 ? data_iterator_.get()
257 : db_iterator_.get(); 234 : db_iterator_.get();
258 235
259 non_current->Seek(Key()); 236 non_current->Seek(Key());
260 if (non_current->IsValid() && 237 if (non_current->IsValid() &&
261 !comparator_->Compare(non_current->Key(), Key())) 238 !comparator_->Compare(non_current->Key(), Key())) {
262 non_current->Next(); // Take an extra step so the non-current key is 239 // Take an extra step so the non-current key is
263 // strictly greater than Key(). 240 // strictly greater than Key().
264 241 non_current->Next();
242 }
265 DCHECK(!non_current->IsValid() || 243 DCHECK(!non_current->IsValid() ||
266 comparator_->Compare(non_current->Key(), Key()) > 0); 244 comparator_->Compare(non_current->Key(), Key()) > 0);
267 245
268 direction_ = FORWARD; 246 direction_ = FORWARD;
269 } 247 }
270 248
271 current_->Next(); 249 current_->Next();
272 HandleConflictsAndDeletes(); 250 HandleConflictsAndDeletes();
273 SetCurrentIteratorToSmallestKey(); 251 SetCurrentIteratorToSmallestKey();
274 } 252 }
275 253
276 void LevelDBTransaction::TransactionIterator::Prev() { 254 void LevelDBTransaction::TransactionIterator::Prev() {
277 DCHECK(IsValid()); 255 DCHECK(IsValid());
278 if (tree_changed_) 256 if (data_changed_)
279 RefreshTreeIterator(); 257 RefreshDataIterator();
280 258
281 if (direction_ != REVERSE) { 259 if (direction_ != REVERSE) {
282 // Ensure the non-current iterator is positioned before Key(). 260 // Ensure the non-current iterator is positioned before Key().
283 261
284 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 262 LevelDBIterator* non_current = (current_ == db_iterator_.get())
285 ? tree_iterator_.get() 263 ? data_iterator_.get()
286 : db_iterator_.get(); 264 : db_iterator_.get();
287 265
288 non_current->Seek(Key()); 266 non_current->Seek(Key());
289 if (non_current->IsValid()) { 267 if (non_current->IsValid()) {
290 // Iterator is at first entry >= Key(). 268 // Iterator is at first entry >= Key().
291 // Step back once to entry < key. 269 // Step back once to entry < key.
292 // This is why we don't check for the keys being the same before 270 // This is why we don't check for the keys being the same before
293 // stepping, like we do in Next() above. 271 // stepping, like we do in Next() above.
294 non_current->Prev(); 272 non_current->Prev();
295 } else { 273 } else {
296 non_current->SeekToLast(); // Iterator has no entries >= Key(). Position 274 // Iterator has no entries >= Key(). Position at last entry.
297 // at last entry. 275 non_current->SeekToLast();
298 } 276 }
299 DCHECK(!non_current->IsValid() || 277 DCHECK(!non_current->IsValid() ||
300 comparator_->Compare(non_current->Key(), Key()) < 0); 278 comparator_->Compare(non_current->Key(), Key()) < 0);
301 279
302 direction_ = REVERSE; 280 direction_ = REVERSE;
303 } 281 }
304 282
305 current_->Prev(); 283 current_->Prev();
306 HandleConflictsAndDeletes(); 284 HandleConflictsAndDeletes();
307 SetCurrentIteratorToLargestKey(); 285 SetCurrentIteratorToLargestKey();
308 } 286 }
309 287
310 StringPiece LevelDBTransaction::TransactionIterator::Key() const { 288 StringPiece LevelDBTransaction::TransactionIterator::Key() const {
311 DCHECK(IsValid()); 289 DCHECK(IsValid());
312 if (tree_changed_) 290 if (data_changed_)
313 RefreshTreeIterator(); 291 RefreshDataIterator();
314 return current_->Key(); 292 return current_->Key();
315 } 293 }
316 294
317 StringPiece LevelDBTransaction::TransactionIterator::Value() const { 295 StringPiece LevelDBTransaction::TransactionIterator::Value() const {
318 DCHECK(IsValid()); 296 DCHECK(IsValid());
319 if (tree_changed_) 297 if (data_changed_)
320 RefreshTreeIterator(); 298 RefreshDataIterator();
321 return current_->Value(); 299 return current_->Value();
322 } 300 }
323 301
324 void LevelDBTransaction::TransactionIterator::TreeChanged() { 302 void LevelDBTransaction::TransactionIterator::DataChanged() {
325 tree_changed_ = true; 303 data_changed_ = true;
326 } 304 }
327 305
328 void LevelDBTransaction::TransactionIterator::RefreshTreeIterator() const { 306 void LevelDBTransaction::TransactionIterator::RefreshDataIterator() const {
329 DCHECK(tree_changed_); 307 DCHECK(data_changed_);
330 308
331 tree_changed_ = false; 309 data_changed_ = false;
332 310
333 if (tree_iterator_->IsValid() && tree_iterator_.get() == current_) { 311 if (data_iterator_->IsValid() && data_iterator_.get() == current_) {
334 tree_iterator_->Reset();
335 return; 312 return;
336 } 313 }
337 314
338 if (db_iterator_->IsValid()) { 315 if (db_iterator_->IsValid()) {
339 // There could be new nodes in the tree that we should iterate over. 316 // There could be new records in data that we should iterate over.
340 317
341 if (direction_ == FORWARD) { 318 if (direction_ == FORWARD) {
342 // Try to seek tree iterator to something greater than the db iterator. 319 // Try to seek data iterator to something greater than the db iterator.
343 tree_iterator_->Seek(db_iterator_->Key()); 320 data_iterator_->Seek(db_iterator_->Key());
344 if (tree_iterator_->IsValid() && 321 if (data_iterator_->IsValid() &&
345 !comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key())) 322 !comparator_->Compare(data_iterator_->Key(), db_iterator_->Key())) {
346 tree_iterator_->Next(); // If equal, take another step so the tree 323 // If equal, take another step so the data iterator is strictly greater.
347 // iterator is strictly greater. 324 data_iterator_->Next();
325 }
348 } else { 326 } else {
349 // If going backward, seek to a key less than the db iterator. 327 // If going backward, seek to a key less than the db iterator.
350 DCHECK_EQ(REVERSE, direction_); 328 DCHECK_EQ(REVERSE, direction_);
351 tree_iterator_->Seek(db_iterator_->Key()); 329 data_iterator_->Seek(db_iterator_->Key());
352 if (tree_iterator_->IsValid()) 330 if (data_iterator_->IsValid())
353 tree_iterator_->Prev(); 331 data_iterator_->Prev();
354 } 332 }
355 } 333 }
356 } 334 }
357 335
358 bool LevelDBTransaction::TransactionIterator::TreeIteratorIsLower() const { 336 bool LevelDBTransaction::TransactionIterator::DataIteratorIsLower() const {
359 return comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()) < 0; 337 return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) < 0;
360 } 338 }
361 339
362 bool LevelDBTransaction::TransactionIterator::TreeIteratorIsHigher() const { 340 bool LevelDBTransaction::TransactionIterator::DataIteratorIsHigher() const {
363 return comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()) > 0; 341 return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) > 0;
364 } 342 }
365 343
366 void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() { 344 void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() {
367 bool loop = true; 345 bool loop = true;
368 346
369 while (loop) { 347 while (loop) {
370 loop = false; 348 loop = false;
371 349
372 if (tree_iterator_->IsValid() && db_iterator_->IsValid() && 350 if (data_iterator_->IsValid() && db_iterator_->IsValid() &&
373 !comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key())) { 351 !comparator_->Compare(data_iterator_->Key(), db_iterator_->Key())) {
374 // For equal keys, the tree iterator takes precedence, so move the 352 // For equal keys, the data iterator takes precedence, so move the
375 // database iterator another step. 353 // database iterator another step.
376 if (direction_ == FORWARD) 354 if (direction_ == FORWARD)
377 db_iterator_->Next(); 355 db_iterator_->Next();
378 else 356 else
379 db_iterator_->Prev(); 357 db_iterator_->Prev();
380 } 358 }
381 359
382 // Skip over delete markers in the tree iterator until it catches up with 360 // Skip over delete markers in the data iterator until it catches up with
383 // the db iterator. 361 // the db iterator.
384 if (tree_iterator_->IsValid() && tree_iterator_->IsDeleted()) { 362 if (data_iterator_->IsValid() && data_iterator_->IsDeleted()) {
385 if (direction_ == FORWARD && 363 if (direction_ == FORWARD &&
386 (!db_iterator_->IsValid() || TreeIteratorIsLower())) { 364 (!db_iterator_->IsValid() || DataIteratorIsLower())) {
387 tree_iterator_->Next(); 365 data_iterator_->Next();
388 loop = true; 366 loop = true;
389 } else if (direction_ == REVERSE && 367 } else if (direction_ == REVERSE &&
390 (!db_iterator_->IsValid() || TreeIteratorIsHigher())) { 368 (!db_iterator_->IsValid() || DataIteratorIsHigher())) {
391 tree_iterator_->Prev(); 369 data_iterator_->Prev();
392 loop = true; 370 loop = true;
393 } 371 }
394 } 372 }
395 } 373 }
396 } 374 }
397 375
398 void 376 void
399 LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() { 377 LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() {
400 LevelDBIterator* smallest = 0; 378 LevelDBIterator* smallest = 0;
401 379
402 if (tree_iterator_->IsValid()) 380 if (data_iterator_->IsValid())
403 smallest = tree_iterator_.get(); 381 smallest = data_iterator_.get();
404 382
405 if (db_iterator_->IsValid()) { 383 if (db_iterator_->IsValid()) {
406 if (!smallest || 384 if (!smallest ||
407 comparator_->Compare(db_iterator_->Key(), smallest->Key()) < 0) 385 comparator_->Compare(db_iterator_->Key(), smallest->Key()) < 0)
408 smallest = db_iterator_.get(); 386 smallest = db_iterator_.get();
409 } 387 }
410 388
411 current_ = smallest; 389 current_ = smallest;
412 } 390 }
413 391
414 void LevelDBTransaction::TransactionIterator::SetCurrentIteratorToLargestKey() { 392 void LevelDBTransaction::TransactionIterator::SetCurrentIteratorToLargestKey() {
415 LevelDBIterator* largest = 0; 393 LevelDBIterator* largest = 0;
416 394
417 if (tree_iterator_->IsValid()) 395 if (data_iterator_->IsValid())
418 largest = tree_iterator_.get(); 396 largest = data_iterator_.get();
419 397
420 if (db_iterator_->IsValid()) { 398 if (db_iterator_->IsValid()) {
421 if (!largest || 399 if (!largest ||
422 comparator_->Compare(db_iterator_->Key(), largest->Key()) > 0) 400 comparator_->Compare(db_iterator_->Key(), largest->Key()) > 0)
423 largest = db_iterator_.get(); 401 largest = db_iterator_.get();
424 } 402 }
425 403
426 current_ = largest; 404 current_ = largest;
427 } 405 }
428 406
429 void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) { 407 void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) {
430 DCHECK(iterators_.find(iterator) == iterators_.end()); 408 DCHECK(iterators_.find(iterator) == iterators_.end());
431 iterators_.insert(iterator); 409 iterators_.insert(iterator);
432 } 410 }
433 411
434 void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) { 412 void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) {
435 DCHECK(iterators_.find(iterator) != iterators_.end()); 413 DCHECK(iterators_.find(iterator) != iterators_.end());
436 iterators_.erase(iterator); 414 iterators_.erase(iterator);
437 } 415 }
438 416
439 void LevelDBTransaction::NotifyIteratorsOfTreeChange() { 417 void LevelDBTransaction::NotifyIterators() {
440 for (std::set<TransactionIterator*>::iterator i = iterators_.begin(); 418 for (std::set<TransactionIterator*>::iterator i = iterators_.begin();
441 i != iterators_.end(); 419 i != iterators_.end();
442 ++i) { 420 ++i) {
443 TransactionIterator* transaction_iterator = *i; 421 TransactionIterator* transaction_iterator = *i;
444 transaction_iterator->TreeChanged(); 422 transaction_iterator->DataChanged();
445 } 423 }
446 } 424 }
447 425
448 scoped_ptr<LevelDBWriteOnlyTransaction> LevelDBWriteOnlyTransaction::Create( 426 scoped_ptr<LevelDBWriteOnlyTransaction> LevelDBWriteOnlyTransaction::Create(
449 LevelDBDatabase* db) { 427 LevelDBDatabase* db) {
450 return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db)); 428 return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db));
451 } 429 }
452 430
453 LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db) 431 LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db)
454 : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {} 432 : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {}
(...skipping 12 matching lines...) Expand all
467 445
468 if (!db_->Write(*write_batch_)) 446 if (!db_->Write(*write_batch_))
469 return false; 447 return false;
470 448
471 finished_ = true; 449 finished_ = true;
472 write_batch_->Clear(); 450 write_batch_->Clear();
473 return true; 451 return true;
474 } 452 }
475 453
476 } // namespace content 454 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/leveldb/leveldb_transaction.h ('k') | content/browser/indexed_db/leveldb/leveldb_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698