// -*- mode: c++; c-basic-offset: 4 -*-
/*
 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef WTF_ListHashSet_h
#define WTF_ListHashSet_h

#include "Assertions.h"
#include "HashSet.h"
#include "OwnPtr.h"

namespace WTF {

    // ListHashSet: Just like HashSet, this class provides a Set
    // interface - a collection of unique objects with O(1) insertion,
    // removal and test for containership. However, it also has an
    // order - iterating it will always give back values in the order
    // in which they are added.

    // In theory it would be possible to add prepend, insertAfter, insertBefore,
    // and an append that moves the element to the end even if already present,
    // but unclear yet if these are needed.

    template<typename Value, typename HashFunctions> class ListHashSet;

    template<typename T> struct IdentityExtractor;

    template<typename Value, typename HashFunctions>
    void deleteAllValues(const ListHashSet<Value, HashFunctions>&);

    template<typename ValueArg, typename HashArg> class ListHashSetIterator;
    template<typename ValueArg, typename HashArg> class ListHashSetConstIterator;

    template<typename ValueArg> struct ListHashSetNode;
    template<typename ValueArg> struct ListHashSetNodeAllocator;
    template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions;

    template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet {
    private:
        typedef ListHashSetNode<ValueArg> Node;
        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;

        typedef HashTraits<Node*> NodeTraits;
        typedef ListHashSetNodeHashFunctions<ValueArg, HashArg> NodeHash;

        typedef HashTable<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplType;

        typedef HashArg HashFunctions;

    public:
        typedef ValueArg ValueType;
        typedef ListHashSetIterator<ValueType, HashArg> iterator;
        typedef ListHashSetConstIterator<ValueType, HashArg> const_iterator;

        friend class ListHashSetConstIterator<ValueType, HashArg>;

        ListHashSet();
        ListHashSet(const ListHashSet&);
        ListHashSet& operator=(const ListHashSet&);
        ~ListHashSet();

        void swap(ListHashSet&);

        int size() const;
        int capacity() const;
        bool isEmpty() const;

        iterator begin();
        iterator end();
        const_iterator begin() const;
        const_iterator end() const;

        iterator find(const ValueType&);
        const_iterator find(const ValueType&) const;
        bool contains(const ValueType&) const;

        // the return value is a pair of an interator to the new value's location, 
        // and a bool that is true if an new entry was added
        pair<iterator, bool> add(const ValueType&);

        void remove(const ValueType&);
        void remove(iterator);
        void clear();

    private:
        void unlinkAndDelete(Node*);
        void appendNode(Node*);
        void deleteAllNodes();
        iterator makeIterator(Node*);
        const_iterator makeConstIterator(Node*) const;

        friend void deleteAllValues<>(const ListHashSet&);

        ImplType m_impl;
        Node* m_head;
        Node* m_tail;
        OwnPtr<NodeAllocator> m_allocator;
    };

    template<typename ValueArg> struct ListHashSetNodeAllocator {
        typedef ListHashSetNode<ValueArg> Node;
        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;

        ListHashSetNodeAllocator() 
            : m_freeList(pool())
            , m_isDoneWithInitialFreeList(false)
        { 
            memset(m_pool.pool, 0, sizeof(m_pool.pool));
        }

        Node* allocate()
        { 
            Node* result = m_freeList;

            if (!result)
                return static_cast<Node*>(fastMalloc(sizeof(Node)));

            ASSERT(!result->m_isAllocated);

            Node* next = result->m_next;
            ASSERT(!next || !next->m_isAllocated);
            if (!next && !m_isDoneWithInitialFreeList) {
                next = result + 1;
                if (next == pastPool()) {
                    m_isDoneWithInitialFreeList = true;
                    next = 0;
                } else {
                    ASSERT(inPool(next));
                    ASSERT(!next->m_isAllocated);
                }
            }
            m_freeList = next;

            return result;
        }

        void deallocate(Node* node) 
        {
            if (inPool(node)) {
#ifndef NDEBUG
                node->m_isAllocated = false;
#endif
                node->m_next = m_freeList;
                m_freeList = node;
                return;
            }

            fastFree(node);
        }

    private:
        Node* pool() { return reinterpret_cast<Node*>(m_pool.pool); }
        Node* pastPool() { return pool() + m_poolSize; }

        bool inPool(Node* node)
        {
            return node >= pool() && node < pastPool();
        }

        Node* m_freeList;
        bool m_isDoneWithInitialFreeList;
        static const size_t m_poolSize = 256;
        union {
            char pool[sizeof(Node) * m_poolSize];
            double forAlignment;
        } m_pool;
    };

    template<typename ValueArg> struct ListHashSetNode {
        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;

        ListHashSetNode(ValueArg value)
            : m_value(value)
            , m_prev(0)
            , m_next(0)
#ifndef NDEBUG
            , m_isAllocated(true)
#endif
        {
        }

        void* operator new(size_t, NodeAllocator* allocator)
        {
            return allocator->allocate();
        }
        void destroy(NodeAllocator* allocator)
        {
            this->~ListHashSetNode();
            allocator->deallocate(this);
        }

        ValueArg m_value;
        ListHashSetNode* m_prev;
        ListHashSetNode* m_next;

#ifndef NDEBUG
        bool m_isAllocated;
#endif
    };

    template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions {
        typedef ListHashSetNode<ValueArg> Node;
        
        static unsigned hash(Node* const& key) { return HashArg::hash(key->m_value); }
        static bool equal(Node* const& a, Node* const& b) { return HashArg::equal(a->m_value, b->m_value); }
    };

    template<typename ValueArg, typename HashArg> class ListHashSetIterator {
    private:
        typedef ListHashSet<ValueArg, HashArg> ListHashSetType;
        typedef ListHashSetIterator<ValueArg, HashArg> iterator;
        typedef ListHashSetConstIterator<ValueArg, HashArg> const_iterator;
        typedef ListHashSetNode<ValueArg> Node;
        typedef ValueArg ValueType;
        typedef ValueType& ReferenceType;
        typedef ValueType* PointerType;

        friend class ListHashSet<ValueArg, HashArg>;

        ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { }

    public:
        ListHashSetIterator() { }

        // default copy, assignment and destructor are OK

        PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
        ReferenceType operator*() const { return *get(); }
        PointerType operator->() const { return get(); }

        iterator& operator++() { ++m_iterator; return *this; }

        // postfix ++ intentionally omitted

        iterator& operator--() { --m_iterator; return *this; }

        // postfix -- intentionally omitted

        // Comparison.
        bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; }
        bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; }

        operator const_iterator() const { return m_iterator; }

    private:
        Node* node() { return m_iterator.node(); }

        const_iterator m_iterator;
    };

    template<typename ValueArg, typename HashArg> class ListHashSetConstIterator {
    private:
        typedef ListHashSet<ValueArg, HashArg> ListHashSetType;
        typedef ListHashSetIterator<ValueArg, HashArg> iterator;
        typedef ListHashSetConstIterator<ValueArg, HashArg> const_iterator;
        typedef ListHashSetNode<ValueArg> Node;
        typedef ValueArg ValueType;
        typedef const ValueType& ReferenceType;
        typedef const ValueType* PointerType;

        friend class ListHashSet<ValueArg, HashArg>;
        friend class ListHashSetIterator<ValueArg, HashArg>;

        ListHashSetConstIterator(const ListHashSetType* set, Node* position)
            : m_set(set)
            , m_position(position)
        {
        }

    public:
        ListHashSetConstIterator()
        {
        }

        PointerType get() const
        {
            return &m_position->m_value;
        }
        ReferenceType operator*() const { return *get(); }
        PointerType operator->() const { return get(); }

        const_iterator& operator++()
        {
            ASSERT(m_position != 0);
            m_position = m_position->m_next;
            return *this;
        }

        // postfix ++ intentionally omitted

        const_iterator& operator--()
        {
            ASSERT(m_position != m_set->m_head);
            m_position = m_position->m_prev;
            return *this;
        }

        // postfix -- intentionally omitted

        // Comparison.
        bool operator==(const const_iterator& other) const
        {
            return m_position == other.m_position;
        }
        bool operator!=(const const_iterator& other) const
        {
            return m_position != other.m_position;
        }

    private:
        Node* node() { return m_position; }

        const ListHashSetType* m_set;
        Node* m_position;
    };


    template<typename ValueType, typename HashFunctions>
    struct ListHashSetTranslator {
    private:
        typedef ListHashSetNode<ValueType> Node;
        typedef ListHashSetNodeAllocator<ValueType> NodeAllocator;
    public:
        static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); }
        static bool equal(Node* const& a, const ValueType& b) { return HashFunctions::equal(a->m_value, b); }
        static void translate(Node*& location, const ValueType& key, NodeAllocator* allocator, unsigned)
        {
            location = new (allocator) Node(key);
        }
    };

    template<typename T, typename U>
    inline ListHashSet<T, U>::ListHashSet()
        : m_head(0)
        , m_tail(0)
        , m_allocator(new NodeAllocator)
    {
    }

    template<typename T, typename U>
    inline ListHashSet<T, U>::ListHashSet(const ListHashSet& other)
        : m_head(0)
        , m_tail(0)
        , m_allocator(new NodeAllocator)
    {
        const_iterator end = other.end();
        for (const_iterator it = other.begin(); it != end; ++it)
            add(*it);
    }

    template<typename T, typename U>
    inline ListHashSet<T, U>& ListHashSet<T, U>::operator=(const ListHashSet& other)
    {
        ListHashSet tmp(other);
        swap(tmp);
        return *this;
    }

    template<typename T, typename U>
    inline void ListHashSet<T, U>::swap(ListHashSet& other)
    {
        m_impl.swap(other.m_impl);
        std::swap(m_head, other.m_head);
        std::swap(m_tail, other.m_tail);
        m_allocator.swap(other.m_allocator);
        return *this;
    }

    template<typename T, typename U>
    inline ListHashSet<T, U>::~ListHashSet()
    {
        deleteAllNodes();
    }

    template<typename T, typename U>
    inline int ListHashSet<T, U>::size() const
    {
        return m_impl.size(); 
    }

    template<typename T, typename U>
    inline int ListHashSet<T, U>::capacity() const
    {
        return m_impl.capacity(); 
    }

    template<typename T, typename U>
    inline bool ListHashSet<T, U>::isEmpty() const
    {
        return m_impl.isEmpty(); 
    }

    template<typename T, typename U>
    inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::begin()
    {
        return makeIterator(m_head); 
    }

    template<typename T, typename U>
    inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::end()
    {
        return makeIterator(0);
    }

    template<typename T, typename U>
    inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::begin() const
    {
        return makeConstIterator(m_head); 
    }

    template<typename T, typename U>
    inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::end() const
    {
        return makeConstIterator(0); 
    }

    template<typename T, typename U>
    inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::find(const ValueType& value)
    {
        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
        typename ImplType::iterator it = m_impl.template find<ValueType, Translator>(value);
        if (it == m_impl.end())
            return end();
        return makeIterator(*it); 
    }

    template<typename T, typename U>
    inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::find(const ValueType& value) const
    {
        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
        typename ImplType::const_iterator it = m_impl.template find<ValueType, Translator>(value);
        if (it == m_impl.end())
            return end();
        return makeConstIterator(*it);
    }

    template<typename T, typename U>
    inline bool ListHashSet<T, U>::contains(const ValueType& value) const
    {
        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
        return m_impl.template contains<ValueType, Translator>(value);
    }

    template<typename T, typename U>
    pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::add(const ValueType &value)
    {
        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
        pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(value, m_allocator.get());
        if (result.second)
            appendNode(*result.first);
        return std::make_pair(makeIterator(*result.first), result.second);
    }

    template<typename T, typename U>
    inline void ListHashSet<T, U>::remove(iterator it)
    {
        if (it == end())
            return;
        m_impl.remove(it.node());
        unlinkAndDelete(it.node());
    }

    template<typename T, typename U>
    inline void ListHashSet<T, U>::remove(const ValueType& value)
    {
        remove(find(value));
    }

    template<typename T, typename U>
    inline void ListHashSet<T, U>::clear()
    {
        deleteAllNodes();
        m_impl.clear(); 
        m_head = 0;
        m_tail = 0;
    }

    template<typename T, typename U>
    void ListHashSet<T, U>::unlinkAndDelete(Node* node)
    {
        if (!node->m_prev) {
            ASSERT(node == m_head);
            m_head = node->m_next;
        } else {
            ASSERT(node != m_head);
            node->m_prev->m_next = node->m_next;
        }

        if (!node->m_next) {
            ASSERT(node == m_tail);
            m_tail = node->m_prev;
        } else {
            ASSERT(node != m_tail);
            node->m_next->m_prev = node->m_prev;
        }

        node->destroy(m_allocator.get());
    }

    template<typename T, typename U>
    void ListHashSet<T, U>::appendNode(Node* node)
    {
        node->m_prev = m_tail;
        node->m_next = 0;

        if (m_tail) {
            ASSERT(m_head);
            m_tail->m_next = node;
        } else {
            ASSERT(!m_head);
            m_head = node;
        }

        m_tail = node;
    }

    template<typename T, typename U>
    void ListHashSet<T, U>::deleteAllNodes()
    {
        if (!m_head)
            return;

        for (Node* node = m_head, *next = m_head->m_next; node; node = next, next = node ? node->m_next : 0)
            node->destroy(m_allocator.get());
    }

    template<typename T, typename U>
    inline ListHashSetIterator<T, U> ListHashSet<T, U>::makeIterator(Node* position) 
    {
        return ListHashSetIterator<T, U>(this, position); 
    }

    template<typename T, typename U>
    inline ListHashSetConstIterator<T, U> ListHashSet<T, U>::makeConstIterator(Node* position) const
    { 
        return ListHashSetConstIterator<T, U>(this, position); 
    }

    template<bool, typename ValueType, typename HashTableType>
    void deleteAllValues(HashTableType& collection)
    {
        typedef typename HashTableType::const_iterator iterator;
        iterator end = collection.end();
        for (iterator it = collection.begin(); it != end; ++it)
            delete (*it)->m_value;
    }

    template<typename T, typename U>
    inline void deleteAllValues(const ListHashSet<T, U>& collection)
    {
        deleteAllValues<true, typename ListHashSet<T, U>::ValueType>(collection.m_impl);
    }

} // namespace WTF

using WTF::ListHashSet;

#endif /* WTF_ListHashSet_h */
