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

Unified 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: Rebased; store node pointers in map to avoid copies Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/indexed_db/leveldb/leveldb_transaction.cc
diff --git a/content/browser/indexed_db/leveldb/leveldb_transaction.cc b/content/browser/indexed_db/leveldb/leveldb_transaction.cc
index 5388d44c6f5ad13fbe09a8d0aa825446fe4a4f26..f52c03d685f1c6046e5d64d10104d488197aec58 100644
--- a/content/browser/indexed_db/leveldb/leveldb_transaction.cc
+++ b/content/browser/indexed_db/leveldb/leveldb_transaction.cc
@@ -14,27 +14,21 @@ using base::StringPiece;
namespace content {
LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db)
- : db_(db), snapshot_(db), comparator_(db->Comparator()), finished_(false) {
- tree_.abstractor().comparator_ = comparator_;
-}
+ : db_(db),
+ snapshot_(db),
+ comparator_(db->Comparator()),
+ tree_comparator_(comparator_),
+ tree_(tree_comparator_),
+ finished_(false) {}
-LevelDBTransaction::AVLTreeNode::AVLTreeNode() {}
-LevelDBTransaction::AVLTreeNode::~AVLTreeNode() {}
+LevelDBTransaction::TreeNode::TreeNode() : deleted(false) {}
+LevelDBTransaction::TreeNode::~TreeNode() {}
void LevelDBTransaction::ClearTree() {
- TreeType::Iterator iterator;
- iterator.StartIterLeast(&tree_);
-
- std::vector<AVLTreeNode*> nodes;
-
- while (*iterator) {
- nodes.push_back(*iterator);
- ++iterator;
+ for (TreeType::iterator it = tree_.begin(); it != tree_.end(); ++it) {
+ delete it->second;
}
- tree_.Purge();
-
- for (size_t i = 0; i < nodes.size(); ++i)
- delete nodes[i];
+ tree_.clear();
}
LevelDBTransaction::~LevelDBTransaction() { ClearTree(); }
@@ -43,20 +37,20 @@ void LevelDBTransaction::Set(const StringPiece& key,
std::string* value,
bool deleted) {
DCHECK(!finished_);
- bool new_node = false;
- AVLTreeNode* node = tree_.Search(key);
-
- if (!node) {
- node = new AVLTreeNode;
- node->key = key.as_string();
- tree_.Insert(node);
- new_node = true;
+ std::string string_key(key.begin(), key.end() - key.begin());
+ TreeType::iterator it = tree_.find(string_key);
+
+ if (it == tree_.end()) {
+ TreeNode* node = new TreeNode();
+ node->value.swap(*value);
+ node->deleted = deleted;
+ tree_[string_key] = node;
+ NotifyIteratorsOfTreeChange();
+ return;
}
- node->value.swap(*value);
- node->deleted = deleted;
- if (new_node)
- NotifyIteratorsOfTreeChange();
+ it->second->value.swap(*value);
+ it->second->deleted = deleted;
}
void LevelDBTransaction::Put(const StringPiece& key, std::string* value) {
@@ -73,13 +67,14 @@ bool LevelDBTransaction::Get(const StringPiece& key,
bool* found) {
*found = false;
DCHECK(!finished_);
- AVLTreeNode* node = tree_.Search(key);
+ std::string string_key(key.begin(), key.end() - key.begin());
alecflett 2013/09/10 16:46:40 Not that this is particularly expensive, but can y
jsbell 2013/09/10 17:00:06 StringPiece doesn't own its storage, and map::find
jsbell 2013/09/10 21:29:36 That turned out to be tricky due to upstream calle
+ TreeType::const_iterator it = tree_.find(string_key);
- if (node) {
- if (node->deleted)
+ if (it != tree_.end()) {
+ if (it->second->deleted)
return true;
- *value = node->value;
+ *value = it->second->value;
alecflett 2013/09/10 16:46:40 it's too bad there's no way to swap or something h
jsbell 2013/09/10 17:00:06 Nope, since the the storage is owned by the tree a
*found = true;
return true;
}
@@ -95,23 +90,19 @@ bool LevelDBTransaction::Get(const StringPiece& key,
bool LevelDBTransaction::Commit() {
DCHECK(!finished_);
- if (tree_.IsEmpty()) {
+ if (tree_.empty()) {
finished_ = true;
return true;
}
scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create();
- TreeType::Iterator iterator;
- iterator.StartIterLeast(&tree_);
-
- while (*iterator) {
- AVLTreeNode* node = *iterator;
- if (!node->deleted)
- write_batch->Put(node->key, node->value);
+ for (TreeType::iterator iterator = tree_.begin(); iterator != tree_.end();
+ ++iterator) {
+ if (!iterator->second->deleted)
+ write_batch->Put(iterator->first, iterator->second->value);
else
- write_batch->Remove(node->key);
- ++iterator;
+ write_batch->Remove(iterator->first);
}
if (!db_->Write(*write_batch))
@@ -137,39 +128,54 @@ LevelDBTransaction::TreeIterator::Create(LevelDBTransaction* transaction) {
return make_scoped_ptr(new TreeIterator(transaction));
}
-bool LevelDBTransaction::TreeIterator::IsValid() const { return !!*iterator_; }
+bool LevelDBTransaction::TreeIterator::IsValid() const {
+ return iterator_ != tree_->end();
+}
void LevelDBTransaction::TreeIterator::SeekToLast() {
- iterator_.StartIterGreatest(tree_);
+ iterator_ = tree_->end();
+ if (iterator_ != tree_->begin())
+ --iterator_;
+
if (IsValid())
- key_ = (*iterator_)->key;
+ key_ = iterator_->first;
}
void LevelDBTransaction::TreeIterator::Seek(const StringPiece& target) {
- iterator_.StartIter(tree_, target, TreeType::EQUAL);
- if (!IsValid())
- iterator_.StartIter(tree_, target, TreeType::GREATER);
+ std::string key(target.begin(), target.end() - target.begin());
alecflett 2013/09/10 16:46:40 copying on a seek seems bad?
jsbell 2013/09/10 17:00:06 I'll look at changing this API here to take a cons
+
+ iterator_ = tree_->find(key);
+ if (!IsValid()) {
+ TreeNode dummy;
ericu 2013/09/10 01:00:41 How about map::lower_bound or map::equal_range?
jsbell 2013/09/10 17:00:06 lower_bound should work - it looks like exactly wh
+ std::pair<TreeType::iterator, bool> position =
+ tree_->insert(make_pair(key, &dummy));
+ iterator_ = position.first;
+ ++iterator_;
+ tree_->erase(position.first);
+ }
if (IsValid())
- key_ = (*iterator_)->key;
+ key_ = iterator_->first;
}
void LevelDBTransaction::TreeIterator::Next() {
DCHECK(IsValid());
++iterator_;
if (IsValid()) {
- DCHECK_GE(transaction_->comparator_->Compare((*iterator_)->key, key_), 0);
- key_ = (*iterator_)->key;
+ DCHECK_GE(transaction_->comparator_->Compare(iterator_->first, key_), 0);
+ key_ = iterator_->first;
}
}
void LevelDBTransaction::TreeIterator::Prev() {
DCHECK(IsValid());
- --iterator_;
+ if (iterator_ != tree_->begin())
+ --iterator_;
+ else
+ iterator_ = tree_->end();
if (IsValid()) {
- DCHECK_LT(tree_->abstractor().comparator_->Compare((*iterator_)->key, key_),
- 0);
- key_ = (*iterator_)->key;
+ DCHECK_LT(transaction_->comparator_->Compare(iterator_->first, key_), 0);
+ key_ = iterator_->first;
}
}
@@ -181,24 +187,26 @@ StringPiece LevelDBTransaction::TreeIterator::Key() const {
StringPiece LevelDBTransaction::TreeIterator::Value() const {
DCHECK(IsValid());
DCHECK(!IsDeleted());
- return (*iterator_)->value;
+ return iterator_->second->value;
}
bool LevelDBTransaction::TreeIterator::IsDeleted() const {
DCHECK(IsValid());
- return (*iterator_)->deleted;
+ return iterator_->second->deleted;
}
void LevelDBTransaction::TreeIterator::Reset() {
DCHECK(IsValid());
- iterator_.StartIter(tree_, key_, TreeType::EQUAL);
+ iterator_ = tree_->find(key_);
DCHECK(IsValid());
}
LevelDBTransaction::TreeIterator::~TreeIterator() {}
LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction)
- : tree_(&transaction->tree_), transaction_(transaction) {}
+ : tree_(&transaction->tree_),
+ iterator_(tree_->end()),
+ transaction_(transaction) {}
scoped_ptr<LevelDBTransaction::TransactionIterator>
LevelDBTransaction::TransactionIterator::Create(

Powered by Google App Engine
This is Rietveld 408576698