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( |