1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 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. 13 * 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. 24 */ 25 26#ifndef LevelDBTransaction_h 27#define LevelDBTransaction_h 28 29#if ENABLE(INDEXED_DATABASE) 30#if USE(LEVELDB) 31 32#include "LevelDBComparator.h" 33#include "LevelDBDatabase.h" 34#include "LevelDBIterator.h" 35#include "LevelDBSlice.h" 36#include <wtf/AVLTree.h> 37#include <wtf/HashSet.h> 38#include <wtf/PassOwnPtr.h> 39#include <wtf/PassRefPtr.h> 40#include <wtf/RefCounted.h> 41#include <wtf/RefPtr.h> 42#include <wtf/Vector.h> 43 44namespace WebCore { 45 46class LevelDBWriteBatch; 47 48using WTF::AVLTree; 49 50class LevelDBTransaction : public RefCounted<LevelDBTransaction> { 51public: 52 static PassRefPtr<LevelDBTransaction> create(LevelDBDatabase*); 53 54 ~LevelDBTransaction(); 55 void put(const LevelDBSlice& key, const Vector<char>& value); 56 void remove(const LevelDBSlice& key); 57 // FIXME: Rename safeGet to get. 58 bool safeGet(const LevelDBSlice& key, Vector<char>& value, bool& found); 59 bool commit(); 60 void rollback(); 61 62 PassOwnPtr<LevelDBIterator> createIterator(); 63 64private: 65 LevelDBTransaction(LevelDBDatabase*); 66 67 struct AVLTreeNode { 68 Vector<char> key; 69 Vector<char> value; 70 bool deleted; 71 72 AVLTreeNode* less; 73 AVLTreeNode* greater; 74 int balanceFactor; 75 }; 76 77 struct AVLTreeAbstractor { 78 typedef AVLTreeNode* handle; 79 typedef size_t size; 80 typedef LevelDBSlice key; 81 82 handle get_less(handle h) { return h->less; } 83 void set_less(handle h, handle less) { h->less = less; } 84 handle get_greater(handle h) { return h->greater; } 85 void set_greater(handle h, handle greater) { h->greater = greater; } 86 87 int get_balance_factor(handle h) { return h->balanceFactor; } 88 void set_balance_factor(handle h, int bf) { h->balanceFactor = bf; } 89 90 int compare_key_key(const key& ka, const key& kb) { return m_comparator->compare(ka, kb); } 91 int compare_key_node(const key& k, handle h) { return compare_key_key(k, h->key); } 92 int compare_node_node(handle ha, handle hb) { return compare_key_key(ha->key, hb->key); } 93 94 static handle null() { return 0; } 95 96 const LevelDBComparator* m_comparator; 97 }; 98 99 typedef AVLTree<AVLTreeAbstractor> TreeType; 100 101 class TreeIterator : public LevelDBIterator { 102 public: 103 static PassOwnPtr<TreeIterator> create(LevelDBTransaction*); 104 ~TreeIterator(); 105 106 virtual bool isValid() const; 107 virtual void seekToLast(); 108 virtual void seek(const LevelDBSlice&); 109 virtual void next(); 110 virtual void prev(); 111 virtual LevelDBSlice key() const; 112 virtual LevelDBSlice value() const; 113 bool isDeleted() const; 114 void reset(); 115 116 private: 117 TreeIterator(LevelDBTransaction*); 118 mutable TreeType::Iterator m_iterator; // Dereferencing this is non-const. 119 TreeType* m_tree; 120 LevelDBTransaction* m_transaction; 121 Vector<char> m_key; 122 }; 123 124 class TransactionIterator : public LevelDBIterator { 125 public: 126 ~TransactionIterator(); 127 static PassOwnPtr<TransactionIterator> create(PassRefPtr<LevelDBTransaction>); 128 129 virtual bool isValid() const; 130 virtual void seekToLast(); 131 virtual void seek(const LevelDBSlice& target); 132 virtual void next(); 133 virtual void prev(); 134 virtual LevelDBSlice key() const; 135 virtual LevelDBSlice value() const; 136 void treeChanged(); 137 138 private: 139 TransactionIterator(PassRefPtr<LevelDBTransaction>); 140 void handleConflictsAndDeletes(); 141 void setCurrentIteratorToSmallestKey(); 142 void setCurrentIteratorToLargestKey(); 143 void refreshTreeIterator() const; 144 bool treeIteratorIsLower() const; 145 bool treeIteratorIsHigher() const; 146 147 RefPtr<LevelDBTransaction> m_transaction; 148 const LevelDBComparator* m_comparator; 149 mutable OwnPtr<TreeIterator> m_treeIterator; 150 OwnPtr<LevelDBIterator> m_dbIterator; 151 LevelDBIterator* m_current; 152 153 enum Direction { 154 kForward, 155 kReverse 156 }; 157 Direction m_direction; 158 mutable bool m_treeChanged; 159 }; 160 161 void set(const LevelDBSlice& key, const Vector<char>& value, bool deleted); 162 void clearTree(); 163 void registerIterator(TransactionIterator*); 164 void unregisterIterator(TransactionIterator*); 165 void notifyIteratorsOfTreeChange(); 166 167 LevelDBDatabase* m_db; 168 const LevelDBSnapshot m_snapshot; 169 const LevelDBComparator* m_comparator; 170 TreeType m_tree; 171 bool m_finished; 172 HashSet<TransactionIterator*> m_iterators; 173}; 174 175class LevelDBWriteOnlyTransaction { 176public: 177 static PassOwnPtr<LevelDBWriteOnlyTransaction> create(LevelDBDatabase*); 178 179 ~LevelDBWriteOnlyTransaction(); 180 void remove(const LevelDBSlice& key); 181 bool commit(); 182 183private: 184 LevelDBWriteOnlyTransaction(LevelDBDatabase*); 185 186 LevelDBDatabase* m_db; 187 OwnPtr<LevelDBWriteBatch> m_writeBatch; 188 bool m_finished; 189}; 190 191} 192 193#endif // USE(LEVELDB) 194#endif // ENABLE(INDEXED_DATABASE) 195 196#endif // LevelDBTransaction_h 197