| 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 <string> |  | 
| 8 |  | 
| 9 #include "base/logging.h" | 7 #include "base/logging.h" | 
| 10 #include "content/browser/indexed_db/leveldb/leveldb_database.h" | 8 #include "content/browser/indexed_db/leveldb/leveldb_database.h" | 
| 11 #include "content/browser/indexed_db/leveldb/leveldb_slice.h" |  | 
| 12 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" | 9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" | 
| 13 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 10 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 
| 14 | 11 | 
|  | 12 using base::StringPiece; | 
|  | 13 | 
| 15 namespace content { | 14 namespace content { | 
| 16 | 15 | 
| 17 scoped_refptr<LevelDBTransaction> LevelDBTransaction::Create( | 16 scoped_refptr<LevelDBTransaction> LevelDBTransaction::Create( | 
| 18     LevelDBDatabase* db) { | 17     LevelDBDatabase* db) { | 
| 19   return make_scoped_refptr(new LevelDBTransaction(db)); | 18   return make_scoped_refptr(new LevelDBTransaction(db)); | 
| 20 } | 19 } | 
| 21 | 20 | 
| 22 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db) | 21 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db) | 
| 23     : db_(db), snapshot_(db), comparator_(db->Comparator()), finished_(false) { | 22     : db_(db), snapshot_(db), comparator_(db->Comparator()), finished_(false) { | 
| 24   tree_.abstractor().comparator_ = comparator_; | 23   tree_.abstractor().comparator_ = comparator_; | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 38     ++iterator; | 37     ++iterator; | 
| 39   } | 38   } | 
| 40   tree_.Purge(); | 39   tree_.Purge(); | 
| 41 | 40 | 
| 42   for (size_t i = 0; i < nodes.size(); ++i) | 41   for (size_t i = 0; i < nodes.size(); ++i) | 
| 43     delete nodes[i]; | 42     delete nodes[i]; | 
| 44 } | 43 } | 
| 45 | 44 | 
| 46 LevelDBTransaction::~LevelDBTransaction() { ClearTree(); } | 45 LevelDBTransaction::~LevelDBTransaction() { ClearTree(); } | 
| 47 | 46 | 
| 48 static void InitVector(const LevelDBSlice& slice, std::vector<char>* vector) { | 47 void LevelDBTransaction::Set(const StringPiece& key, | 
| 49   vector->clear(); | 48                              std::string* value, | 
| 50   vector->insert(vector->end(), slice.begin(), slice.end()); |  | 
| 51 } |  | 
| 52 |  | 
| 53 void LevelDBTransaction::Set(const LevelDBSlice& key, |  | 
| 54                              std::vector<char>* value, |  | 
| 55                              bool deleted) { | 49                              bool deleted) { | 
| 56   DCHECK(!finished_); | 50   DCHECK(!finished_); | 
| 57   bool new_node = false; | 51   bool new_node = false; | 
| 58   AVLTreeNode* node = tree_.Search(key); | 52   AVLTreeNode* node = tree_.Search(key); | 
| 59 | 53 | 
| 60   if (!node) { | 54   if (!node) { | 
| 61     node = new AVLTreeNode; | 55     node = new AVLTreeNode; | 
| 62     InitVector(key, &node->key); | 56     node->key = key.as_string(); | 
| 63     tree_.Insert(node); | 57     tree_.Insert(node); | 
| 64     new_node = true; | 58     new_node = true; | 
| 65   } | 59   } | 
| 66   node->value.swap(*value); | 60   node->value.swap(*value); | 
| 67   node->deleted = deleted; | 61   node->deleted = deleted; | 
| 68 | 62 | 
| 69   if (new_node) | 63   if (new_node) | 
| 70     NotifyIteratorsOfTreeChange(); | 64     NotifyIteratorsOfTreeChange(); | 
| 71 } | 65 } | 
| 72 | 66 | 
| 73 void LevelDBTransaction::Put(const LevelDBSlice& key, | 67 void LevelDBTransaction::Put(const StringPiece& key, std::string* value) { | 
| 74                              std::vector<char>* value) { |  | 
| 75   Set(key, value, false); | 68   Set(key, value, false); | 
| 76 } | 69 } | 
| 77 | 70 | 
| 78 void LevelDBTransaction::Remove(const LevelDBSlice& key) { | 71 void LevelDBTransaction::Remove(const StringPiece& key) { | 
| 79   std::vector<char> empty; | 72   std::string empty; | 
| 80   Set(key, &empty, true); | 73   Set(key, &empty, true); | 
| 81 } | 74 } | 
| 82 | 75 | 
| 83 bool LevelDBTransaction::Get(const LevelDBSlice& key, | 76 bool LevelDBTransaction::Get(const StringPiece& key, | 
| 84                              std::string* value, | 77                              std::string* value, | 
| 85                              bool* found) { | 78                              bool* found) { | 
| 86   *found = false; | 79   *found = false; | 
| 87   DCHECK(!finished_); | 80   DCHECK(!finished_); | 
| 88   AVLTreeNode* node = tree_.Search(key); | 81   AVLTreeNode* node = tree_.Search(key); | 
| 89 | 82 | 
| 90   if (node) { | 83   if (node) { | 
| 91     if (node->deleted) | 84     if (node->deleted) | 
| 92       return true; | 85       return true; | 
| 93 | 86 | 
| 94     value->assign(node->value.begin(), node->value.end()); | 87     *value = node->value; | 
| 95     *found = true; | 88     *found = true; | 
| 96     return true; | 89     return true; | 
| 97   } | 90   } | 
| 98 | 91 | 
| 99   bool ok = db_->Get(key, value, found, &snapshot_); | 92   bool ok = db_->Get(key, value, found, &snapshot_); | 
| 100   if (!ok) { | 93   if (!ok) { | 
| 101     DCHECK(!*found); | 94     DCHECK(!*found); | 
| 102     return false; | 95     return false; | 
| 103   } | 96   } | 
| 104   return true; | 97   return true; | 
| 105 } | 98 } | 
| 106 | 99 | 
| 107 bool LevelDBTransaction::Commit() { | 100 bool LevelDBTransaction::Commit() { | 
| 108   DCHECK(!finished_); | 101   DCHECK(!finished_); | 
| 109 | 102 | 
| 110   if (tree_.IsEmpty()) { | 103   if (tree_.IsEmpty()) { | 
| 111     finished_ = true; | 104     finished_ = true; | 
| 112     return true; | 105     return true; | 
| 113   } | 106   } | 
| 114 | 107 | 
| 115   scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create(); | 108   scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create(); | 
| 116 | 109 | 
| 117   TreeType::Iterator iterator; | 110   TreeType::Iterator iterator; | 
| 118   iterator.StartIterLeast(&tree_); | 111   iterator.StartIterLeast(&tree_); | 
| 119 | 112 | 
| 120   while (*iterator) { | 113   while (*iterator) { | 
| 121     AVLTreeNode* node = *iterator; | 114     AVLTreeNode* node = *iterator; | 
| 122     if (!node->deleted) | 115     if (!node->deleted) | 
| 123       write_batch->Put(LevelDBSlice(node->key), LevelDBSlice(node->value)); | 116       write_batch->Put(node->key, node->value); | 
| 124     else | 117     else | 
| 125       write_batch->Remove(LevelDBSlice(node->key)); | 118       write_batch->Remove(node->key); | 
| 126     ++iterator; | 119     ++iterator; | 
| 127   } | 120   } | 
| 128 | 121 | 
| 129   if (!db_->Write(*write_batch)) | 122   if (!db_->Write(*write_batch)) | 
| 130     return false; | 123     return false; | 
| 131 | 124 | 
| 132   ClearTree(); | 125   ClearTree(); | 
| 133   finished_ = true; | 126   finished_ = true; | 
| 134   return true; | 127   return true; | 
| 135 } | 128 } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 150 } | 143 } | 
| 151 | 144 | 
| 152 bool LevelDBTransaction::TreeIterator::IsValid() const { return !!*iterator_; } | 145 bool LevelDBTransaction::TreeIterator::IsValid() const { return !!*iterator_; } | 
| 153 | 146 | 
| 154 void LevelDBTransaction::TreeIterator::SeekToLast() { | 147 void LevelDBTransaction::TreeIterator::SeekToLast() { | 
| 155   iterator_.StartIterGreatest(tree_); | 148   iterator_.StartIterGreatest(tree_); | 
| 156   if (IsValid()) | 149   if (IsValid()) | 
| 157     key_ = (*iterator_)->key; | 150     key_ = (*iterator_)->key; | 
| 158 } | 151 } | 
| 159 | 152 | 
| 160 void LevelDBTransaction::TreeIterator::Seek(const LevelDBSlice& target) { | 153 void LevelDBTransaction::TreeIterator::Seek(const StringPiece& target) { | 
| 161   iterator_.StartIter(tree_, target, TreeType::EQUAL); | 154   iterator_.StartIter(tree_, target, TreeType::EQUAL); | 
| 162   if (!IsValid()) | 155   if (!IsValid()) | 
| 163     iterator_.StartIter(tree_, target, TreeType::GREATER); | 156     iterator_.StartIter(tree_, target, TreeType::GREATER); | 
| 164 | 157 | 
| 165   if (IsValid()) | 158   if (IsValid()) | 
| 166     key_ = (*iterator_)->key; | 159     key_ = (*iterator_)->key; | 
| 167 } | 160 } | 
| 168 | 161 | 
| 169 void LevelDBTransaction::TreeIterator::Next() { | 162 void LevelDBTransaction::TreeIterator::Next() { | 
| 170   DCHECK(IsValid()); | 163   DCHECK(IsValid()); | 
| 171   ++iterator_; | 164   ++iterator_; | 
| 172   if (IsValid()) { | 165   if (IsValid()) { | 
| 173     DCHECK(transaction_->comparator_->Compare(LevelDBSlice((*iterator_)->key), | 166     DCHECK_GE(transaction_->comparator_->Compare((*iterator_)->key, key_), 0); | 
| 174                                               LevelDBSlice(key_)) > |  | 
| 175            0); |  | 
| 176     key_ = (*iterator_)->key; | 167     key_ = (*iterator_)->key; | 
| 177   } | 168   } | 
| 178 } | 169 } | 
| 179 | 170 | 
| 180 void LevelDBTransaction::TreeIterator::Prev() { | 171 void LevelDBTransaction::TreeIterator::Prev() { | 
| 181   DCHECK(IsValid()); | 172   DCHECK(IsValid()); | 
| 182   --iterator_; | 173   --iterator_; | 
| 183   if (IsValid()) { | 174   if (IsValid()) { | 
| 184     DCHECK(tree_->abstractor().comparator_->Compare( | 175     DCHECK_LT(tree_->abstractor().comparator_->Compare((*iterator_)->key, key_), | 
| 185                LevelDBSlice((*iterator_)->key), LevelDBSlice(key_)) < | 176               0); | 
| 186            0); |  | 
| 187     key_ = (*iterator_)->key; | 177     key_ = (*iterator_)->key; | 
| 188   } | 178   } | 
| 189 } | 179 } | 
| 190 | 180 | 
| 191 LevelDBSlice LevelDBTransaction::TreeIterator::Key() const { | 181 StringPiece LevelDBTransaction::TreeIterator::Key() const { | 
| 192   DCHECK(IsValid()); | 182   DCHECK(IsValid()); | 
| 193   return LevelDBSlice(key_); | 183   return key_; | 
| 194 } | 184 } | 
| 195 | 185 | 
| 196 LevelDBSlice LevelDBTransaction::TreeIterator::Value() const { | 186 StringPiece LevelDBTransaction::TreeIterator::Value() const { | 
| 197   DCHECK(IsValid()); | 187   DCHECK(IsValid()); | 
| 198   DCHECK(!IsDeleted()); | 188   DCHECK(!IsDeleted()); | 
| 199   return LevelDBSlice((*iterator_)->value); | 189   return (*iterator_)->value; | 
| 200 } | 190 } | 
| 201 | 191 | 
| 202 bool LevelDBTransaction::TreeIterator::IsDeleted() const { | 192 bool LevelDBTransaction::TreeIterator::IsDeleted() const { | 
| 203   DCHECK(IsValid()); | 193   DCHECK(IsValid()); | 
| 204   return (*iterator_)->deleted; | 194   return (*iterator_)->deleted; | 
| 205 } | 195 } | 
| 206 | 196 | 
| 207 void LevelDBTransaction::TreeIterator::Reset() { | 197 void LevelDBTransaction::TreeIterator::Reset() { | 
| 208   DCHECK(IsValid()); | 198   DCHECK(IsValid()); | 
| 209   iterator_.StartIter(tree_, LevelDBSlice(key_), TreeType::EQUAL); | 199   iterator_.StartIter(tree_, key_, TreeType::EQUAL); | 
| 210   DCHECK(IsValid()); | 200   DCHECK(IsValid()); | 
| 211 } | 201 } | 
| 212 | 202 | 
| 213 LevelDBTransaction::TreeIterator::~TreeIterator() {} | 203 LevelDBTransaction::TreeIterator::~TreeIterator() {} | 
| 214 | 204 | 
| 215 LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction) | 205 LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction) | 
| 216     : tree_(&transaction->tree_), transaction_(transaction) {} | 206     : tree_(&transaction->tree_), transaction_(transaction) {} | 
| 217 | 207 | 
| 218 scoped_ptr<LevelDBTransaction::TransactionIterator> | 208 scoped_ptr<LevelDBTransaction::TransactionIterator> | 
| 219 LevelDBTransaction::TransactionIterator::Create( | 209 LevelDBTransaction::TransactionIterator::Create( | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 243 | 233 | 
| 244 void LevelDBTransaction::TransactionIterator::SeekToLast() { | 234 void LevelDBTransaction::TransactionIterator::SeekToLast() { | 
| 245   tree_iterator_->SeekToLast(); | 235   tree_iterator_->SeekToLast(); | 
| 246   db_iterator_->SeekToLast(); | 236   db_iterator_->SeekToLast(); | 
| 247   direction_ = REVERSE; | 237   direction_ = REVERSE; | 
| 248 | 238 | 
| 249   HandleConflictsAndDeletes(); | 239   HandleConflictsAndDeletes(); | 
| 250   SetCurrentIteratorToLargestKey(); | 240   SetCurrentIteratorToLargestKey(); | 
| 251 } | 241 } | 
| 252 | 242 | 
| 253 void LevelDBTransaction::TransactionIterator::Seek(const LevelDBSlice& target) { | 243 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { | 
| 254   tree_iterator_->Seek(target); | 244   tree_iterator_->Seek(target); | 
| 255   db_iterator_->Seek(target); | 245   db_iterator_->Seek(target); | 
| 256   direction_ = FORWARD; | 246   direction_ = FORWARD; | 
| 257 | 247 | 
| 258   HandleConflictsAndDeletes(); | 248   HandleConflictsAndDeletes(); | 
| 259   SetCurrentIteratorToSmallestKey(); | 249   SetCurrentIteratorToSmallestKey(); | 
| 260 } | 250 } | 
| 261 | 251 | 
| 262 void LevelDBTransaction::TransactionIterator::Next() { | 252 void LevelDBTransaction::TransactionIterator::Next() { | 
| 263   DCHECK(IsValid()); | 253   DCHECK(IsValid()); | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 315            comparator_->Compare(non_current->Key(), Key()) < 0); | 305            comparator_->Compare(non_current->Key(), Key()) < 0); | 
| 316 | 306 | 
| 317     direction_ = REVERSE; | 307     direction_ = REVERSE; | 
| 318   } | 308   } | 
| 319 | 309 | 
| 320   current_->Prev(); | 310   current_->Prev(); | 
| 321   HandleConflictsAndDeletes(); | 311   HandleConflictsAndDeletes(); | 
| 322   SetCurrentIteratorToLargestKey(); | 312   SetCurrentIteratorToLargestKey(); | 
| 323 } | 313 } | 
| 324 | 314 | 
| 325 LevelDBSlice LevelDBTransaction::TransactionIterator::Key() const { | 315 StringPiece LevelDBTransaction::TransactionIterator::Key() const { | 
| 326   DCHECK(IsValid()); | 316   DCHECK(IsValid()); | 
| 327   if (tree_changed_) | 317   if (tree_changed_) | 
| 328     RefreshTreeIterator(); | 318     RefreshTreeIterator(); | 
| 329   return current_->Key(); | 319   return current_->Key(); | 
| 330 } | 320 } | 
| 331 | 321 | 
| 332 LevelDBSlice LevelDBTransaction::TransactionIterator::Value() const { | 322 StringPiece LevelDBTransaction::TransactionIterator::Value() const { | 
| 333   DCHECK(IsValid()); | 323   DCHECK(IsValid()); | 
| 334   if (tree_changed_) | 324   if (tree_changed_) | 
| 335     RefreshTreeIterator(); | 325     RefreshTreeIterator(); | 
| 336   return current_->Value(); | 326   return current_->Value(); | 
| 337 } | 327 } | 
| 338 | 328 | 
| 339 void LevelDBTransaction::TransactionIterator::TreeChanged() { | 329 void LevelDBTransaction::TransactionIterator::TreeChanged() { | 
| 340   tree_changed_ = true; | 330   tree_changed_ = true; | 
| 341 } | 331 } | 
| 342 | 332 | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 465   return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db)); | 455   return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db)); | 
| 466 } | 456 } | 
| 467 | 457 | 
| 468 LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db) | 458 LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db) | 
| 469     : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {} | 459     : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {} | 
| 470 | 460 | 
| 471 LevelDBWriteOnlyTransaction::~LevelDBWriteOnlyTransaction() { | 461 LevelDBWriteOnlyTransaction::~LevelDBWriteOnlyTransaction() { | 
| 472   write_batch_->Clear(); | 462   write_batch_->Clear(); | 
| 473 } | 463 } | 
| 474 | 464 | 
| 475 void LevelDBWriteOnlyTransaction::Remove(const LevelDBSlice& key) { | 465 void LevelDBWriteOnlyTransaction::Remove(const StringPiece& key) { | 
| 476   DCHECK(!finished_); | 466   DCHECK(!finished_); | 
| 477   write_batch_->Remove(key); | 467   write_batch_->Remove(key); | 
| 478 } | 468 } | 
| 479 | 469 | 
| 480 bool LevelDBWriteOnlyTransaction::Commit() { | 470 bool LevelDBWriteOnlyTransaction::Commit() { | 
| 481   DCHECK(!finished_); | 471   DCHECK(!finished_); | 
| 482 | 472 | 
| 483   if (!db_->Write(*write_batch_)) | 473   if (!db_->Write(*write_batch_)) | 
| 484     return false; | 474     return false; | 
| 485 | 475 | 
| 486   finished_ = true; | 476   finished_ = true; | 
| 487   write_batch_->Clear(); | 477   write_batch_->Clear(); | 
| 488   return true; | 478   return true; | 
| 489 } | 479 } | 
| 490 | 480 | 
| 491 }  // namespace content | 481 }  // namespace content | 
| OLD | NEW | 
|---|