WebCore/storage/IDBKeyTree.h
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebCore/storage/IDBKeyTree.h	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2010 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 IDBKeyTree_h
+#define IDBKeyTree_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBKey.h"
+#include <wtf/AVLTree.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+template <typename ValueType>
+class IDBKeyTree : public RefCounted<IDBKeyTree<ValueType> > {
+public:
+    static PassRefPtr<IDBKeyTree> create()
+    {
+        return adoptRef(new IDBKeyTree());
+    }
+    ~IDBKeyTree();
+
+    ValueType* get(IDBKey* key);
+    void put(IDBKey* key, ValueType* value);
+    void remove(IDBKey* key);
+
+private:
+    struct TreeNode {
+        RefPtr<ValueType> value;
+        RefPtr<IDBKey> key;
+
+        TreeNode* less;
+        TreeNode* greater;
+        int balanceFactor;
+    };
+
+    struct AVLTreeAbstractor {
+        typedef TreeNode* handle;
+        typedef size_t size;
+        typedef IDBKey* key;
+
+        handle get_less(handle h) { return h->less; }
+        void set_less(handle h, handle lh) { h->less = lh; }
+        handle get_greater(handle h) { return h->greater; }
+        void set_greater(handle h, handle gh) { h->greater = gh; }
+        int get_balance_factor(handle h) { return h->balanceFactor; }
+        void set_balance_factor(handle h, int bf) { h->balanceFactor = bf; }
+
+        static handle null() { return 0; }
+
+        int compare_key_key(key va, key vb);
+        int compare_key_node(key k, handle h) { return compare_key_key(k, h->key.get()); }
+        int compare_node_node(handle h1, handle h2) { return compare_key_key(h1->key.get(), h2->key.get()); }
+    };
+
+    IDBKeyTree();
+
+    typedef WTF::AVLTree<AVLTreeAbstractor> TreeType;
+    TreeType m_tree;
+};
+
+template <typename ValueType>
+IDBKeyTree<ValueType>::IDBKeyTree()
+{
+}
+
+template <typename ValueType>
+IDBKeyTree<ValueType>::~IDBKeyTree()
+{
+    typename TreeType::Iterator iter;
+    iter.start_iter_least(m_tree);
+    for (; *iter; ++iter)
+        delete *iter;
+    m_tree.purge();
+}
+
+template <typename ValueType>
+int IDBKeyTree<ValueType>::AVLTreeAbstractor::compare_key_key(key va, key vb)
+{
+    if (va->type() != vb->type())
+        return vb->type() - va->type();
+
+    switch (va->type()) {
+    case IDBKey::NullType:
+        return 0;
+    case IDBKey::NumberType:
+        return vb->number() - va->number();
+    case IDBKey::StringType:
+        return codePointCompare(va->string(), vb->string());
+    // FIXME: Handle dates.  Oh, and test this thoroughly.
+    default:
+        ASSERT_NOT_REACHED();
+        return 0;
+    }
+}
+
+template <typename ValueType>
+ValueType* IDBKeyTree<ValueType>::get(IDBKey* key)
+{
+    TreeNode* node = m_tree.search(key);
+    if (!node)
+        return 0;
+    return node->value.get();
+}
+
+template <typename ValueType>
+void IDBKeyTree<ValueType>::put(IDBKey* key, ValueType* value)
+{
+    TreeNode* node = m_tree.search(key);
+    if (!node) {
+        node = new TreeNode();
+        node->key = key;
+        m_tree.insert(node);
+    }
+    node->value = value;
+}
+
+template <typename ValueType>
+void IDBKeyTree<ValueType>::remove(IDBKey* key)
+{
+    TreeNode* node = m_tree.remove(key);
+    if (node)
+        delete node;
+}
+
+}
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBKeyTree_h