blob: 26eb65f77b5749a42a3a80a70c7f0e22e743a2bc [file] [log] [blame]
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LevelDBTransaction_h
#define LevelDBTransaction_h
#if ENABLE(INDEXED_DATABASE)
#if USE(LEVELDB)
#include "LevelDBComparator.h"
#include "LevelDBDatabase.h"
#include "LevelDBIterator.h"
#include "LevelDBSlice.h"
#include <wtf/AVLTree.h>
#include <wtf/HashSet.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
class LevelDBWriteBatch;
using WTF::AVLTree;
class LevelDBTransaction : public RefCounted<LevelDBTransaction> {
public:
static PassRefPtr<LevelDBTransaction> create(LevelDBDatabase*);
~LevelDBTransaction();
void put(const LevelDBSlice& key, const Vector<char>& value);
void remove(const LevelDBSlice& key);
// FIXME: Rename safeGet to get.
bool safeGet(const LevelDBSlice& key, Vector<char>& value, bool& found);
bool commit();
void rollback();
PassOwnPtr<LevelDBIterator> createIterator();
private:
LevelDBTransaction(LevelDBDatabase*);
struct AVLTreeNode {
Vector<char> key;
Vector<char> value;
bool deleted;
AVLTreeNode* less;
AVLTreeNode* greater;
int balanceFactor;
};
struct AVLTreeAbstractor {
typedef AVLTreeNode* handle;
typedef size_t size;
typedef LevelDBSlice key;
handle get_less(handle h) { return h->less; }
void set_less(handle h, handle less) { h->less = less; }
handle get_greater(handle h) { return h->greater; }
void set_greater(handle h, handle greater) { h->greater = greater; }
int get_balance_factor(handle h) { return h->balanceFactor; }
void set_balance_factor(handle h, int bf) { h->balanceFactor = bf; }
int compare_key_key(const key& ka, const key& kb) { return m_comparator->compare(ka, kb); }
int compare_key_node(const key& k, handle h) { return compare_key_key(k, h->key); }
int compare_node_node(handle ha, handle hb) { return compare_key_key(ha->key, hb->key); }
static handle null() { return 0; }
const LevelDBComparator* m_comparator;
};
typedef AVLTree<AVLTreeAbstractor> TreeType;
class TreeIterator : public LevelDBIterator {
public:
static PassOwnPtr<TreeIterator> create(LevelDBTransaction*);
~TreeIterator();
virtual bool isValid() const;
virtual void seekToLast();
virtual void seek(const LevelDBSlice&);
virtual void next();
virtual void prev();
virtual LevelDBSlice key() const;
virtual LevelDBSlice value() const;
bool isDeleted() const;
void reset();
private:
TreeIterator(LevelDBTransaction*);
mutable TreeType::Iterator m_iterator; // Dereferencing this is non-const.
TreeType* m_tree;
LevelDBTransaction* m_transaction;
Vector<char> m_key;
};
class TransactionIterator : public LevelDBIterator {
public:
~TransactionIterator();
static PassOwnPtr<TransactionIterator> create(PassRefPtr<LevelDBTransaction>);
virtual bool isValid() const;
virtual void seekToLast();
virtual void seek(const LevelDBSlice& target);
virtual void next();
virtual void prev();
virtual LevelDBSlice key() const;
virtual LevelDBSlice value() const;
void treeChanged();
private:
TransactionIterator(PassRefPtr<LevelDBTransaction>);
void handleConflictsAndDeletes();
void setCurrentIteratorToSmallestKey();
void setCurrentIteratorToLargestKey();
void refreshTreeIterator() const;
bool treeIteratorIsLower() const;
bool treeIteratorIsHigher() const;
RefPtr<LevelDBTransaction> m_transaction;
const LevelDBComparator* m_comparator;
mutable OwnPtr<TreeIterator> m_treeIterator;
OwnPtr<LevelDBIterator> m_dbIterator;
LevelDBIterator* m_current;
enum Direction {
kForward,
kReverse
};
Direction m_direction;
mutable bool m_treeChanged;
};
void set(const LevelDBSlice& key, const Vector<char>& value, bool deleted);
void clearTree();
void registerIterator(TransactionIterator*);
void unregisterIterator(TransactionIterator*);
void notifyIteratorsOfTreeChange();
LevelDBDatabase* m_db;
const LevelDBSnapshot m_snapshot;
const LevelDBComparator* m_comparator;
TreeType m_tree;
bool m_finished;
HashSet<TransactionIterator*> m_iterators;
};
class LevelDBWriteOnlyTransaction {
public:
static PassOwnPtr<LevelDBWriteOnlyTransaction> create(LevelDBDatabase*);
~LevelDBWriteOnlyTransaction();
void remove(const LevelDBSlice& key);
bool commit();
private:
LevelDBWriteOnlyTransaction(LevelDBDatabase*);
LevelDBDatabase* m_db;
OwnPtr<LevelDBWriteBatch> m_writeBatch;
bool m_finished;
};
}
#endif // USE(LEVELDB)
#endif // ENABLE(INDEXED_DATABASE)
#endif // LevelDBTransaction_h