summaryrefslogtreecommitdiffstats
path: root/content/browser/indexed_db/leveldb/leveldb_transaction.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/indexed_db/leveldb/leveldb_transaction.cc')
-rw-r--r--content/browser/indexed_db/leveldb/leveldb_transaction.cc490
1 files changed, 0 insertions, 490 deletions
diff --git a/content/browser/indexed_db/leveldb/leveldb_transaction.cc b/content/browser/indexed_db/leveldb/leveldb_transaction.cc
deleted file mode 100644
index a8b3a3d..0000000
--- a/content/browser/indexed_db/leveldb/leveldb_transaction.cc
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
-
-#include "base/logging.h"
-#include "content/browser/indexed_db/leveldb/leveldb_database.h"
-#include "content/browser/indexed_db/leveldb/leveldb_slice.h"
-#include "content/browser/indexed_db/leveldb/leveldb_write_batch.h"
-#include "third_party/leveldatabase/src/include/leveldb/db.h"
-
-namespace content {
-
-scoped_refptr<LevelDBTransaction> LevelDBTransaction::Create(
- LevelDBDatabase* db) {
- return make_scoped_refptr(new LevelDBTransaction(db));
-}
-
-LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db)
- : db_(db), snapshot_(db), comparator_(db->Comparator()), finished_(false) {
- tree_.abstractor().comparator_ = comparator_;
-}
-
-LevelDBTransaction::AVLTreeNode::AVLTreeNode() {}
-LevelDBTransaction::AVLTreeNode::~AVLTreeNode() {}
-
-void LevelDBTransaction::ClearTree() {
- TreeType::Iterator iterator;
- iterator.start_iter_least(tree_);
-
- std::vector<AVLTreeNode*> nodes;
-
- while (*iterator) {
- nodes.push_back(*iterator);
- ++iterator;
- }
- tree_.purge();
-
- for (size_t i = 0; i < nodes.size(); ++i)
- delete nodes[i];
-}
-
-LevelDBTransaction::~LevelDBTransaction() { ClearTree(); }
-
-static void InitVector(const LevelDBSlice& slice, std::vector<char>* vector) {
- vector->clear();
- vector->insert(vector->end(), slice.begin(), slice.end());
-}
-
-void LevelDBTransaction::Set(const LevelDBSlice& key,
- const std::vector<char>& value,
- bool deleted) {
- DCHECK(!finished_);
- bool new_node = false;
- AVLTreeNode* node = tree_.search(key);
-
- if (!node) {
- node = new AVLTreeNode;
- InitVector(key, &node->key);
- tree_.insert(node);
- new_node = true;
- }
- node->value = value;
- node->deleted = deleted;
-
- if (new_node)
- NotifyIteratorsOfTreeChange();
-}
-
-void LevelDBTransaction::Put(const LevelDBSlice& key,
- const std::vector<char>& value) {
- Set(key, value, false);
-}
-
-void LevelDBTransaction::Remove(const LevelDBSlice& key) {
- Set(key, std::vector<char>(), true);
-}
-
-bool LevelDBTransaction::Get(const LevelDBSlice& key,
- std::vector<char>& value,
- bool& found) {
- found = false;
- DCHECK(!finished_);
- AVLTreeNode* node = tree_.search(key);
-
- if (node) {
- if (node->deleted)
- return true;
-
- value = node->value;
- found = true;
- return true;
- }
-
- bool ok = db_->Get(key, value, found, &snapshot_);
- if (!ok) {
- DCHECK(!found);
- return false;
- }
- return true;
-}
-
-bool LevelDBTransaction::Commit() {
- DCHECK(!finished_);
-
- if (tree_.is_empty()) {
- finished_ = true;
- return true;
- }
-
- scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create();
-
- TreeType::Iterator iterator;
- iterator.start_iter_least(tree_);
-
- while (*iterator) {
- AVLTreeNode* node = *iterator;
- if (!node->deleted)
- write_batch->Put(LevelDBSlice(node->key), LevelDBSlice(node->value));
- else
- write_batch->Remove(LevelDBSlice(node->key));
- ++iterator;
- }
-
- if (!db_->Write(*write_batch))
- return false;
-
- ClearTree();
- finished_ = true;
- return true;
-}
-
-void LevelDBTransaction::Rollback() {
- DCHECK(!finished_);
- finished_ = true;
- ClearTree();
-}
-
-scoped_ptr<LevelDBIterator> LevelDBTransaction::CreateIterator() {
- return TransactionIterator::Create(this).PassAs<LevelDBIterator>();
-}
-
-scoped_ptr<LevelDBTransaction::TreeIterator>
-LevelDBTransaction::TreeIterator::Create(LevelDBTransaction* transaction) {
- return make_scoped_ptr(new TreeIterator(transaction));
-}
-
-bool LevelDBTransaction::TreeIterator::IsValid() const { return !!*iterator_; }
-
-void LevelDBTransaction::TreeIterator::SeekToLast() {
- iterator_.start_iter_greatest(*tree_);
- if (IsValid())
- key_ = (*iterator_)->key;
-}
-
-void LevelDBTransaction::TreeIterator::Seek(const LevelDBSlice& target) {
- iterator_.start_iter(*tree_, target, TreeType::EQUAL);
- if (!IsValid())
- iterator_.start_iter(*tree_, target, TreeType::GREATER);
-
- if (IsValid())
- key_ = (*iterator_)->key;
-}
-
-void LevelDBTransaction::TreeIterator::Next() {
- DCHECK(IsValid());
- ++iterator_;
- if (IsValid()) {
- DCHECK(transaction_->comparator_->Compare(LevelDBSlice((*iterator_)->key),
- LevelDBSlice(key_)) >
- 0);
- (void) transaction_;
- key_ = (*iterator_)->key;
- }
-}
-
-void LevelDBTransaction::TreeIterator::Prev() {
- DCHECK(IsValid());
- --iterator_;
- if (IsValid()) {
- DCHECK(tree_->abstractor().comparator_->Compare(
- LevelDBSlice((*iterator_)->key), LevelDBSlice(key_)) <
- 0);
- key_ = (*iterator_)->key;
- }
-}
-
-LevelDBSlice LevelDBTransaction::TreeIterator::Key() const {
- DCHECK(IsValid());
- return LevelDBSlice(key_);
-}
-
-LevelDBSlice LevelDBTransaction::TreeIterator::Value() const {
- DCHECK(IsValid());
- DCHECK(!IsDeleted());
- return LevelDBSlice((*iterator_)->value);
-}
-
-bool LevelDBTransaction::TreeIterator::IsDeleted() const {
- DCHECK(IsValid());
- return (*iterator_)->deleted;
-}
-
-void LevelDBTransaction::TreeIterator::Reset() {
- DCHECK(IsValid());
- iterator_.start_iter(*tree_, LevelDBSlice(key_), TreeType::EQUAL);
- DCHECK(IsValid());
-}
-
-LevelDBTransaction::TreeIterator::~TreeIterator() {}
-
-LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction)
- : tree_(&transaction->tree_), transaction_(transaction) {}
-
-scoped_ptr<LevelDBTransaction::TransactionIterator>
-LevelDBTransaction::TransactionIterator::Create(
- scoped_refptr<LevelDBTransaction> transaction) {
- return make_scoped_ptr(new TransactionIterator(transaction));
-}
-
-LevelDBTransaction::TransactionIterator::TransactionIterator(
- scoped_refptr<LevelDBTransaction> transaction)
- : transaction_(transaction),
- comparator_(transaction_->comparator_),
- tree_iterator_(TreeIterator::Create(transaction_.get())),
- db_iterator_(transaction_->db_->CreateIterator(&transaction_->snapshot_)),
- current_(0),
- direction_(FORWARD),
- tree_changed_(false) {
- transaction_->RegisterIterator(this);
-}
-
-LevelDBTransaction::TransactionIterator::~TransactionIterator() {
- transaction_->UnregisterIterator(this);
-}
-
-bool LevelDBTransaction::TransactionIterator::IsValid() const {
- return !!current_;
-}
-
-void LevelDBTransaction::TransactionIterator::SeekToLast() {
- tree_iterator_->SeekToLast();
- db_iterator_->SeekToLast();
- direction_ = REVERSE;
-
- HandleConflictsAndDeletes();
- SetCurrentIteratorToLargestKey();
-}
-
-void LevelDBTransaction::TransactionIterator::Seek(const LevelDBSlice& target) {
- tree_iterator_->Seek(target);
- db_iterator_->Seek(target);
- direction_ = FORWARD;
-
- HandleConflictsAndDeletes();
- SetCurrentIteratorToSmallestKey();
-}
-
-void LevelDBTransaction::TransactionIterator::Next() {
- DCHECK(IsValid());
- if (tree_changed_)
- RefreshTreeIterator();
-
- if (direction_ != FORWARD) {
- // Ensure the non-current iterator is positioned after Key().
-
- LevelDBIterator* non_current =
- (current_ == db_iterator_.get()) ? tree_iterator_.get()
- : db_iterator_.get();
-
- non_current->Seek(Key());
- if (non_current->IsValid() &&
- !comparator_->Compare(non_current->Key(), Key()))
- non_current->Next(); // Take an extra step so the non-current key is
- // strictly greater than Key().
-
- DCHECK(!non_current->IsValid() ||
- comparator_->Compare(non_current->Key(), Key()) > 0);
-
- direction_ = FORWARD;
- }
-
- current_->Next();
- HandleConflictsAndDeletes();
- SetCurrentIteratorToSmallestKey();
-}
-
-void LevelDBTransaction::TransactionIterator::Prev() {
- DCHECK(IsValid());
- if (tree_changed_)
- RefreshTreeIterator();
-
- if (direction_ != REVERSE) {
- // Ensure the non-current iterator is positioned before Key().
-
- LevelDBIterator* non_current =
- (current_ == db_iterator_.get()) ? tree_iterator_.get()
- : db_iterator_.get();
-
- non_current->Seek(Key());
- if (non_current->IsValid()) {
- // Iterator is at first entry >= Key().
- // Step back once to entry < key.
- // This is why we don't check for the keys being the same before
- // stepping, like we do in Next() above.
- non_current->Prev();
- } else {
- non_current->SeekToLast(); // Iterator has no entries >= Key(). Position
- // at last entry.
- }
- DCHECK(!non_current->IsValid() ||
- comparator_->Compare(non_current->Key(), Key()) < 0);
-
- direction_ = REVERSE;
- }
-
- current_->Prev();
- HandleConflictsAndDeletes();
- SetCurrentIteratorToLargestKey();
-}
-
-LevelDBSlice LevelDBTransaction::TransactionIterator::Key() const {
- DCHECK(IsValid());
- if (tree_changed_)
- RefreshTreeIterator();
- return current_->Key();
-}
-
-LevelDBSlice LevelDBTransaction::TransactionIterator::Value() const {
- DCHECK(IsValid());
- if (tree_changed_)
- RefreshTreeIterator();
- return current_->Value();
-}
-
-void LevelDBTransaction::TransactionIterator::TreeChanged() {
- tree_changed_ = true;
-}
-
-void LevelDBTransaction::TransactionIterator::RefreshTreeIterator() const {
- DCHECK(tree_changed_);
-
- tree_changed_ = false;
-
- if (tree_iterator_->IsValid() && tree_iterator_.get() == current_) {
- tree_iterator_->Reset();
- return;
- }
-
- if (db_iterator_->IsValid()) {
-
- // There could be new nodes in the tree that we should iterate over.
-
- if (direction_ == FORWARD) {
- // Try to seek tree iterator to something greater than the db iterator.
- tree_iterator_->Seek(db_iterator_->Key());
- if (tree_iterator_->IsValid() &&
- !comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()))
- tree_iterator_->Next(); // If equal, take another step so the tree
- // iterator is strictly greater.
- } else {
- // If going backward, seek to a key less than the db iterator.
- DCHECK_EQ(REVERSE, direction_);
- tree_iterator_->Seek(db_iterator_->Key());
- if (tree_iterator_->IsValid())
- tree_iterator_->Prev();
- }
- }
-}
-
-bool LevelDBTransaction::TransactionIterator::TreeIteratorIsLower() const {
- return comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()) < 0;
-}
-
-bool LevelDBTransaction::TransactionIterator::TreeIteratorIsHigher() const {
- return comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()) > 0;
-}
-
-void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() {
- bool loop = true;
-
- while (loop) {
- loop = false;
-
- if (tree_iterator_->IsValid() && db_iterator_->IsValid() &&
- !comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key())) {
- // For equal keys, the tree iterator takes precedence, so move the
- // database iterator another step.
- if (direction_ == FORWARD)
- db_iterator_->Next();
- else
- db_iterator_->Prev();
- }
-
- // Skip over delete markers in the tree iterator until it catches up with
- // the db iterator.
- if (tree_iterator_->IsValid() && tree_iterator_->IsDeleted()) {
- if (direction_ == FORWARD &&
- (!db_iterator_->IsValid() || TreeIteratorIsLower())) {
- tree_iterator_->Next();
- loop = true;
- } else if (direction_ == REVERSE &&
- (!db_iterator_->IsValid() || TreeIteratorIsHigher())) {
- tree_iterator_->Prev();
- loop = true;
- }
- }
- }
-}
-
-void
-LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() {
- LevelDBIterator* smallest = 0;
-
- if (tree_iterator_->IsValid())
- smallest = tree_iterator_.get();
-
- if (db_iterator_->IsValid()) {
- if (!smallest ||
- comparator_->Compare(db_iterator_->Key(), smallest->Key()) < 0)
- smallest = db_iterator_.get();
- }
-
- current_ = smallest;
-}
-
-void LevelDBTransaction::TransactionIterator::SetCurrentIteratorToLargestKey() {
- LevelDBIterator* largest = 0;
-
- if (tree_iterator_->IsValid())
- largest = tree_iterator_.get();
-
- if (db_iterator_->IsValid()) {
- if (!largest ||
- comparator_->Compare(db_iterator_->Key(), largest->Key()) > 0)
- largest = db_iterator_.get();
- }
-
- current_ = largest;
-}
-
-void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) {
- DCHECK(iterators_.find(iterator) == iterators_.end());
- iterators_.insert(iterator);
-}
-
-void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) {
- DCHECK(iterators_.find(iterator) != iterators_.end());
- iterators_.erase(iterator);
-}
-
-void LevelDBTransaction::NotifyIteratorsOfTreeChange() {
- for (std::set<TransactionIterator*>::iterator i = iterators_.begin();
- i != iterators_.end();
- ++i) {
- TransactionIterator* transaction_iterator = *i;
- transaction_iterator->TreeChanged();
- }
-}
-
-scoped_ptr<LevelDBWriteOnlyTransaction> LevelDBWriteOnlyTransaction::Create(
- LevelDBDatabase* db) {
- return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db));
-}
-
-LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db)
- : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {}
-
-LevelDBWriteOnlyTransaction::~LevelDBWriteOnlyTransaction() {
- write_batch_->Clear();
-}
-
-void LevelDBWriteOnlyTransaction::Remove(const LevelDBSlice& key) {
- DCHECK(!finished_);
- write_batch_->Remove(key);
-}
-
-bool LevelDBWriteOnlyTransaction::Commit() {
- DCHECK(!finished_);
-
- if (!db_->Write(*write_batch_))
- return false;
-
- finished_ = true;
- write_batch_->Clear();
- return true;
-}
-
-} // namespace content