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