⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hashtable.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008 David Levin <levin@chromium.org> * * 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_HashTable_h#define WTF_HashTable_h#include "FastMalloc.h"#include "HashTraits.h"#include <wtf/Assertions.h>#include <wtf/Threading.h>namespace WTF {#define DUMP_HASHTABLE_STATS 0#define CHECK_HASHTABLE_CONSISTENCY 0#ifdef NDEBUG#define CHECK_HASHTABLE_ITERATORS 0#define CHECK_HASHTABLE_USE_AFTER_DESTRUCTION 0#else#define CHECK_HASHTABLE_ITERATORS 1#define CHECK_HASHTABLE_USE_AFTER_DESTRUCTION 1#endif#if DUMP_HASHTABLE_STATS    struct HashTableStats {        ~HashTableStats();        // All of the variables are accessed in ~HashTableStats when the static struct is destroyed.        // The following variables are all atomically incremented when modified.        static int numAccesses;        static int numRehashes;        static int numRemoves;        static int numReinserts;        // The following variables are only modified in the recordCollisionAtCount method within a mutex.        static int maxCollisions;        static int numCollisions;        static int collisionGraph[4096];        static void recordCollisionAtCount(int count);    };#endif    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    class HashTable;    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    class HashTableIterator;    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    class HashTableConstIterator;    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    void addIterator(const HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*,        HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*);    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    void removeIterator(HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*);#if !CHECK_HASHTABLE_ITERATORS    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    inline void addIterator(const HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*,        HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*) { }    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    inline void removeIterator(HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*) { }#endif    typedef enum { HashItemKnownGood } HashItemKnownGoodTag;    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    class HashTableConstIterator {    private:        typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> HashTableType;        typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> iterator;        typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator;        typedef Value ValueType;        typedef const ValueType& ReferenceType;        typedef const ValueType* PointerType;        friend class HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>;        friend class HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>;        void skipEmptyBuckets()        {            while (m_position != m_endPosition && HashTableType::isEmptyOrDeletedBucket(*m_position))                ++m_position;        }        HashTableConstIterator(const HashTableType* table, PointerType position, PointerType endPosition)            : m_position(position), m_endPosition(endPosition)        {            addIterator(table, this);            skipEmptyBuckets();        }        HashTableConstIterator(const HashTableType* table, PointerType position, PointerType endPosition, HashItemKnownGoodTag)            : m_position(position), m_endPosition(endPosition)        {            addIterator(table, this);        }    public:        HashTableConstIterator()        {            addIterator(0, this);        }        // default copy, assignment and destructor are OK if CHECK_HASHTABLE_ITERATORS is 0#if CHECK_HASHTABLE_ITERATORS        ~HashTableConstIterator()        {            removeIterator(this);        }        HashTableConstIterator(const const_iterator& other)            : m_position(other.m_position), m_endPosition(other.m_endPosition)        {            addIterator(other.m_table, this);        }        const_iterator& operator=(const const_iterator& other)        {            m_position = other.m_position;            m_endPosition = other.m_endPosition;            removeIterator(this);            addIterator(other.m_table, this);            return *this;        }#endif        PointerType get() const        {            checkValidity();            return m_position;        }        ReferenceType operator*() const { return *get(); }        PointerType operator->() const { return get(); }        const_iterator& operator++()        {            checkValidity();            ASSERT(m_position != m_endPosition);            ++m_position;            skipEmptyBuckets();            return *this;        }        // postfix ++ intentionally omitted        // Comparison.        bool operator==(const const_iterator& other) const        {            checkValidity(other);            return m_position == other.m_position;        }        bool operator!=(const const_iterator& other) const        {            checkValidity(other);            return m_position != other.m_position;        }    private:        void checkValidity() const        {#if CHECK_HASHTABLE_ITERATORS            ASSERT(m_table);#endif        }#if CHECK_HASHTABLE_ITERATORS        void checkValidity(const const_iterator& other) const        {            ASSERT(m_table);            ASSERT(other.m_table);            ASSERT(m_table == other.m_table);        }#else        void checkValidity(const const_iterator&) const { }#endif        PointerType m_position;        PointerType m_endPosition;#if CHECK_HASHTABLE_ITERATORS    public:        // Any modifications of the m_next or m_previous of an iterator that is in a linked list of a HashTable::m_iterator,        // should be guarded with m_table->m_mutex.        mutable const HashTableType* m_table;        mutable const_iterator* m_next;        mutable const_iterator* m_previous;#endif    };    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    class HashTableIterator {    private:        typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> HashTableType;        typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> iterator;        typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator;        typedef Value ValueType;        typedef ValueType& ReferenceType;        typedef ValueType* PointerType;        friend class HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>;        HashTableIterator(HashTableType* table, PointerType pos, PointerType end) : m_iterator(table, pos, end) { }        HashTableIterator(HashTableType* table, PointerType pos, PointerType end, HashItemKnownGoodTag tag) : m_iterator(table, pos, end, tag) { }    public:        HashTableIterator() { }        // 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        // 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:        const_iterator m_iterator;    };    using std::swap;#if !COMPILER(MSVC)    // Visual C++ has a swap for pairs defined.    // swap pairs by component, in case of pair members that specialize swap    template<typename T, typename U> inline void swap(pair<T, U>& a, pair<T, U>& b)    {        swap(a.first, b.first);        swap(a.second, b.second);    }#endif    template<typename T, bool useSwap> struct Mover;    template<typename T> struct Mover<T, true> { static void move(T& from, T& to) { swap(from, to); } };    template<typename T> struct Mover<T, false> { static void move(T& from, T& to) { to = from; } };    template<typename Key, typename Value, typename HashFunctions> class IdentityHashTranslator {    public:        static unsigned hash(const Key& key) { return HashFunctions::hash(key); }        static bool equal(const Key& a, const Key& b) { return HashFunctions::equal(a, b); }        static void translate(Value& location, const Key&, const Value& value) { location = value; }    };    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>    class HashTable {    public:        typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> iterator;        typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator;        typedef Traits ValueTraits;        typedef Key KeyType;        typedef Value ValueType;        typedef IdentityHashTranslator<Key, Value, HashFunctions> IdentityTranslatorType;        HashTable();        ~HashTable()         {            invalidateIterators();             deallocateTable(m_table, m_tableSize); #if CHECK_HASHTABLE_USE_AFTER_DESTRUCTION            m_table = (ValueType*)(uintptr_t)0xbbadbeef;#endif        }        HashTable(const HashTable&);        void swap(HashTable&);        HashTable& operator=(const HashTable&);        iterator begin() { return makeIterator(m_table); }        iterator end() { return makeKnownGoodIterator(m_table + m_tableSize); }        const_iterator begin() const { return makeConstIterator(m_table); }        const_iterator end() const { return makeKnownGoodConstIterator(m_table + m_tableSize); }        int size() const { return m_keyCount; }        int capacity() const { return m_tableSize; }        bool isEmpty() const { return !m_keyCount; }        pair<iterator, bool> add(const ValueType& value) { return add<KeyType, ValueType, IdentityTranslatorType>(Extractor::extract(value), value); }        // A special version of add() that finds the object by hashing and comparing        // with some other type, to avoid the cost of type conversion if the object is already        // in the table.        template<typename T, typename Extra, typename HashTranslator> pair<iterator, bool> add(const T& key, const Extra&);        template<typename T, typename Extra, typename HashTranslator> pair<iterator, bool> addPassingHashCode(const T& key, const Extra&);        iterator find(const KeyType& key) { return find<KeyType, IdentityTranslatorType>(key); }        const_iterator find(const KeyType& key) const { return find<KeyType, IdentityTranslatorType>(key); }        bool contains(const KeyType& key) const { return contains<KeyType, IdentityTranslatorType>(key); }        template <typename T, typename HashTranslator> iterator find(const T&);        template <typename T, typename HashTranslator> const_iterator find(const T&) const;        template <typename T, typename HashTranslator> bool contains(const T&) const;        void remove(const KeyType&);        void remove(iterator);        void removeWithoutEntryConsistencyCheck(iterator);        void clear();        static bool isEmptyBucket(const ValueType& value) { return Extractor::extract(value) == KeyTraits::emptyValue(); }        static bool isDeletedBucket(const ValueType& value) { return KeyTraits::isDeletedValue(Extractor::extract(value)); }        static bool isEmptyOrDeletedBucket(const ValueType& value) { return isEmptyBucket(value) || isDeletedBucket(value); }        ValueType* lookup(const Key& key) { return lookup<Key, IdentityTranslatorType>(key); }        template<typename T, typename HashTranslator> ValueType* lookup(const T&);#if CHECK_HASHTABLE_CONSISTENCY        void checkTableConsistency() const;#else        static void checkTableConsistency() { }#endif    private:        static ValueType* allocateTable(int size);        static void deallocateTable(ValueType* table, int size);        typedef pair<ValueType*, bool> LookupType;        typedef pair<LookupType, unsigned> FullLookupType;        LookupType lookupForWriting(const Key& key) { return lookupForWriting<Key, IdentityTranslatorType>(key); };        template<typename T, typename HashTranslator> FullLookupType fullLookupForWriting(const T&);        template<typename T, typename HashTranslator> LookupType lookupForWriting(const T&);        template<typename T, typename HashTranslator> void checkKey(const T&);        void removeAndInvalidateWithoutEntryConsistencyCheck(ValueType*);        void removeAndInvalidate(ValueType*);        void remove(ValueType*);        bool shouldExpand() const { return (m_keyCount + m_deletedCount) * m_maxLoad >= m_tableSize; }        bool mustRehashInPlace() const { return m_keyCount * m_minLoad < m_tableSize * 2; }        bool shouldShrink() const { return m_keyCount * m_minLoad < m_tableSize && m_tableSize > m_minTableSize; }        void expand();        void shrink() { rehash(m_tableSize / 2); }        void rehash(int newTableSize);        void reinsert(ValueType&);        static void initializeBucket(ValueType& bucket) { new (&bucket) ValueType(Traits::emptyValue()); }        static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Traits::constructDeletedValue(bucket); }        FullLookupType makeLookupResult(ValueType* position, bool found, unsigned hash)            { return FullLookupType(LookupType(position, found), hash); }        iterator makeIterator(ValueType* pos) { return iterator(this, pos, m_table + m_tableSize); }        const_iterator makeConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize); }        iterator makeKnownGoodIterator(ValueType* pos) { return iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); }        const_iterator makeKnownGoodConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); }#if CHECK_HASHTABLE_CONSISTENCY        void checkTableConsistencyExceptSize() const;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -