| OLD | NEW |
| 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 Loading... |
| 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 |
| OLD | NEW |