2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "LevelDBTransaction.h"
29 #include "LevelDBDatabase.h"
30 #include "LevelDBSlice.h"
31 #include "LevelDBWriteBatch.h"
33 #if ENABLE(INDEXED_DATABASE)
38 PassRefPtr<LevelDBTransaction> LevelDBTransaction::create(LevelDBDatabase* db)
40 return adoptRef(new LevelDBTransaction(db));
43 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db)
45 , m_comparator(db->comparator())
48 m_tree.abstractor().m_comparator = m_comparator;
51 void LevelDBTransaction::clearTree()
53 TreeType::Iterator iterator;
54 iterator.start_iter_least(m_tree);
56 Vector<AVLTreeNode*> nodes;
59 nodes.append(*iterator);
64 for (size_t i = 0; i < nodes.size(); ++i)
68 LevelDBTransaction::~LevelDBTransaction()
73 static void initVector(const LevelDBSlice& slice, Vector<char>* vector)
76 vector->append(slice.begin(), slice.end() - slice.begin());
79 bool LevelDBTransaction::set(const LevelDBSlice& key, const Vector<char>& value, bool deleted)
83 AVLTreeNode* node = m_tree.search(key);
86 node = new AVLTreeNode;
87 initVector(key, &node->key);
92 node->deleted = deleted;
95 notifyIteratorsOfTreeChange();
99 bool LevelDBTransaction::put(const LevelDBSlice& key, const Vector<char>& value)
101 return set(key, value, false);
104 bool LevelDBTransaction::remove(const LevelDBSlice& key)
106 return set(key, Vector<char>(), true);
109 bool LevelDBTransaction::get(const LevelDBSlice& key, Vector<char>& value)
112 AVLTreeNode* node = m_tree.search(key);
122 return m_db->get(key, value);
125 bool LevelDBTransaction::commit()
128 OwnPtr<LevelDBWriteBatch> writeBatch = LevelDBWriteBatch::create();
130 TreeType::Iterator iterator;
131 iterator.start_iter_least(m_tree);
134 AVLTreeNode* node = *iterator;
136 writeBatch->put(node->key, node->value);
138 writeBatch->remove(node->key);
142 if (!m_db->write(*writeBatch))
150 void LevelDBTransaction::rollback()
157 PassOwnPtr<LevelDBIterator> LevelDBTransaction::createIterator()
159 return TransactionIterator::create(this);
162 PassOwnPtr<LevelDBTransaction::TreeIterator> LevelDBTransaction::TreeIterator::create(LevelDBTransaction* transaction)
164 return adoptPtr(new TreeIterator(transaction));
167 bool LevelDBTransaction::TreeIterator::isValid() const
172 void LevelDBTransaction::TreeIterator::seekToLast()
174 m_iterator.start_iter_greatest(*m_tree);
176 m_key = (*m_iterator)->key;
179 void LevelDBTransaction::TreeIterator::seek(const LevelDBSlice& target)
181 m_iterator.start_iter(*m_tree, target, TreeType::EQUAL);
183 m_iterator.start_iter(*m_tree, target, TreeType::GREATER);
186 m_key = (*m_iterator)->key;
189 void LevelDBTransaction::TreeIterator::next()
194 ASSERT(m_transaction->m_comparator->compare((*m_iterator)->key, m_key) > 0);
195 m_key = (*m_iterator)->key;
199 void LevelDBTransaction::TreeIterator::prev()
204 ASSERT(m_tree->abstractor().m_comparator->compare((*m_iterator)->key, m_key) < 0);
205 m_key = (*m_iterator)->key;
209 LevelDBSlice LevelDBTransaction::TreeIterator::key() const
215 LevelDBSlice LevelDBTransaction::TreeIterator::value() const
218 ASSERT(!isDeleted());
219 return (*m_iterator)->value;
222 bool LevelDBTransaction::TreeIterator::isDeleted() const
225 return (*m_iterator)->deleted;
228 void LevelDBTransaction::TreeIterator::reset()
231 m_iterator.start_iter(*m_tree, m_key, TreeType::EQUAL);
235 LevelDBTransaction::TreeIterator::~TreeIterator()
239 LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction)
240 : m_tree(&transaction->m_tree)
241 , m_transaction(transaction)
245 PassOwnPtr<LevelDBTransaction::TransactionIterator> LevelDBTransaction::TransactionIterator::create(PassRefPtr<LevelDBTransaction> transaction)
247 return adoptPtr(new TransactionIterator(transaction));
250 LevelDBTransaction::TransactionIterator::TransactionIterator(PassRefPtr<LevelDBTransaction> transaction)
251 : m_transaction(transaction)
252 , m_comparator(m_transaction->m_comparator)
253 , m_treeIterator(TreeIterator::create(m_transaction.get()))
254 , m_dbIterator(m_transaction->m_db->createIterator())
256 , m_direction(kForward)
257 , m_treeChanged(false)
259 m_transaction->registerIterator(this);
262 LevelDBTransaction::TransactionIterator::~TransactionIterator()
264 m_transaction->unregisterIterator(this);
267 bool LevelDBTransaction::TransactionIterator::isValid() const
272 void LevelDBTransaction::TransactionIterator::seekToLast()
274 m_treeIterator->seekToLast();
275 m_dbIterator->seekToLast();
276 m_direction = kReverse;
278 handleConflictsAndDeletes();
279 setCurrentIteratorToLargestKey();
282 void LevelDBTransaction::TransactionIterator::seek(const LevelDBSlice& target)
284 m_treeIterator->seek(target);
285 m_dbIterator->seek(target);
286 m_direction = kForward;
288 handleConflictsAndDeletes();
289 setCurrentIteratorToSmallestKey();
292 void LevelDBTransaction::TransactionIterator::next()
296 refreshTreeIterator();
298 if (m_direction != kForward) {
299 // Ensure the non-current iterator is positioned after key().
301 LevelDBIterator* nonCurrent = (m_current == m_dbIterator.get()) ? m_treeIterator.get() : m_dbIterator.get();
303 nonCurrent->seek(key());
304 if (nonCurrent->isValid() && !m_comparator->compare(nonCurrent->key(), key()))
305 nonCurrent->next(); // Take an extra step so the non-current key is strictly greater than key().
307 ASSERT(!nonCurrent->isValid() || m_comparator->compare(nonCurrent->key(), key()) > 0);
309 m_direction = kForward;
313 handleConflictsAndDeletes();
314 setCurrentIteratorToSmallestKey();
317 void LevelDBTransaction::TransactionIterator::prev()
321 refreshTreeIterator();
323 if (m_direction != kReverse) {
324 // Ensure the non-current iterator is positioned before key().
326 LevelDBIterator* nonCurrent = (m_current == m_dbIterator.get()) ? m_treeIterator.get() : m_dbIterator.get();
328 nonCurrent->seek(key());
329 if (nonCurrent->isValid()) {
330 // Iterator is at first entry >= key().
331 // Step back once to entry < key.
332 // This is why we don't check for the keys being the same before
333 // stepping, like we do in next() above.
336 nonCurrent->seekToLast(); // Iterator has no entries >= key(). Position at last entry.
338 ASSERT(!nonCurrent->isValid() || m_comparator->compare(nonCurrent->key(), key()) < 0);
340 m_direction = kReverse;
344 handleConflictsAndDeletes();
345 setCurrentIteratorToLargestKey();
348 LevelDBSlice LevelDBTransaction::TransactionIterator::key() const
352 refreshTreeIterator();
353 return m_current->key();
356 LevelDBSlice LevelDBTransaction::TransactionIterator::value() const
360 refreshTreeIterator();
361 return m_current->value();
364 void LevelDBTransaction::TransactionIterator::treeChanged()
366 m_treeChanged = true;
369 void LevelDBTransaction::TransactionIterator::refreshTreeIterator() const
371 ASSERT(m_treeChanged);
373 if (m_treeIterator->isValid()) {
374 m_treeIterator->reset();
378 if (m_dbIterator->isValid()) {
379 ASSERT(!m_treeIterator->isValid());
381 // There could be new nodes in the tree that we should iterate over.
383 if (m_direction == kForward) {
384 // Try to seek tree iterator to something greater than the db iterator.
385 m_treeIterator->seek(m_dbIterator->key());
386 if (m_treeIterator->isValid() && !m_comparator->compare(m_treeIterator->key(), m_dbIterator->key()))
387 m_treeIterator->next(); // If equal, take another step so the tree iterator is strictly greater.
389 // If going backward, seek to a key less than the db iterator.
390 ASSERT(m_direction == kReverse);
391 m_treeIterator->seek(m_dbIterator->key());
392 if (m_treeIterator->isValid())
393 m_treeIterator->prev();
397 m_treeChanged = false;
400 void LevelDBTransaction::TransactionIterator::handleConflictsAndDeletes()
407 if (m_treeIterator->isValid() && m_dbIterator->isValid() && !m_comparator->compare(m_treeIterator->key(), m_dbIterator->key())) {
408 // For equal keys, the tree iterator takes precedence, so move the database iterator another step.
409 if (m_direction == kForward)
410 m_dbIterator->next();
412 m_dbIterator->prev();
415 if (m_treeIterator->isValid() && m_treeIterator->isDeleted()) {
416 // If the tree iterator is on a delete marker, take another step.
417 if (m_direction == kForward)
418 m_treeIterator->next();
420 m_treeIterator->prev();
427 void LevelDBTransaction::TransactionIterator::setCurrentIteratorToSmallestKey()
429 LevelDBIterator* smallest = 0;
431 if (m_treeIterator->isValid())
432 smallest = m_treeIterator.get();
434 if (m_dbIterator->isValid()) {
435 if (!smallest || m_comparator->compare(m_dbIterator->key(), smallest->key()) < 0)
436 smallest = m_dbIterator.get();
439 m_current = smallest;
442 void LevelDBTransaction::TransactionIterator::setCurrentIteratorToLargestKey()
444 LevelDBIterator* largest = 0;
446 if (m_treeIterator->isValid())
447 largest = m_treeIterator.get();
449 if (m_dbIterator->isValid()) {
450 if (!largest || m_comparator->compare(m_dbIterator->key(), largest->key()) > 0)
451 largest = m_dbIterator.get();
457 void LevelDBTransaction::registerIterator(TransactionIterator* iterator)
459 ASSERT(!m_iterators.contains(iterator));
460 m_iterators.add(iterator);
463 void LevelDBTransaction::unregisterIterator(TransactionIterator* iterator)
465 ASSERT(m_iterators.contains(iterator));
466 m_iterators.remove(iterator);
469 void LevelDBTransaction::notifyIteratorsOfTreeChange()
471 for (HashSet<TransactionIterator*>::iterator i = m_iterators.begin(); i != m_iterators.end(); ++i) {
472 TransactionIterator* transactionIterator = *i;
473 transactionIterator->treeChanged();
477 } // namespace WebCore
479 #endif // ENABLE(LEVELDB)
480 #endif // ENABLE(INDEXED_DATABASE)