]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - wtf/RefPtrHashMap.h
JavaScriptCore-721.26.tar.gz
[apple/javascriptcore.git] / wtf / RefPtrHashMap.h
index 0515a24ba5cebdcbf6ddf7ec42156201378d65cb..7f6ebfeaddae442097f3d692cf72203e5decbbe9 100644 (file)
@@ -1,6 +1,5 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008 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
@@ -24,14 +23,30 @@ namespace WTF {
     // This specialization is a direct copy of HashMap, with overloaded functions
     // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
     
-    // FIXME: Is there a better way to do this that doesn't just copy HashMap?
+    // FIXME: Find a better way that doesn't require an entire copy of the HashMap template.
     
+    template<typename RawKeyType, typename ValueType, typename ValueTraits, typename HashFunctions>
+    struct RefPtrHashMapRawKeyTranslator {
+        typedef typename ValueType::first_type KeyType;
+        typedef typename ValueType::second_type MappedType;
+        typedef typename ValueTraits::FirstTraits KeyTraits;
+        typedef typename ValueTraits::SecondTraits MappedTraits;
+
+        static unsigned hash(RawKeyType key) { return HashFunctions::hash(key); }
+        static bool equal(const KeyType& a, RawKeyType b) { return HashFunctions::equal(a, b); }
+        static void translate(ValueType& location, RawKeyType key, const MappedType& mapped)
+        {
+            location.first = key;
+            location.second = mapped;
+        }
+    };
+
     template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
-    class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> {
+    class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> : public FastAllocBase {
     private:
         typedef KeyTraitsArg KeyTraits;
         typedef MappedTraitsArg MappedTraits;
-        typedef PairBaseHashTraits<KeyTraits, MappedTraits> ValueTraits;
+        typedef PairHashTraits<KeyTraits, MappedTraits> ValueTraits;
 
     public:
         typedef typename KeyTraits::TraitType KeyType;
@@ -42,28 +57,16 @@ namespace WTF {
     private:
         typedef HashArg HashFunctions;
 
-        typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Hash StorageHashFunctions;
-
-        typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Traits KeyStorageTraits;
-        typedef typename MappedTraits::StorageTraits MappedStorageTraits;
-        typedef PairHashTraits<KeyStorageTraits, MappedStorageTraits> ValueStorageTraits;
+        typedef HashTable<KeyType, ValueType, PairFirstExtractor<ValueType>,
+            HashFunctions, ValueTraits, KeyTraits> HashTableType;
 
-        typedef typename KeyStorageTraits::TraitType KeyStorageType;
-        typedef typename MappedStorageTraits::TraitType MappedStorageType;
-        typedef typename ValueStorageTraits::TraitType ValueStorageType;
-
-        typedef HashTable<KeyStorageType, ValueStorageType, PairFirstExtractor<ValueStorageType>,
-            StorageHashFunctions, ValueStorageTraits, KeyStorageTraits> HashTableType;
+        typedef RefPtrHashMapRawKeyTranslator<RawKeyType, ValueType, ValueTraits, HashFunctions>
+            RawKeyTranslator;
 
     public:
         typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
         typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
 
-        HashMap();
-        HashMap(const HashMap&);
-        HashMap& operator=(const HashMap&);
-        ~HashMap();
-
         void swap(HashMap&);
 
         int size() const;
@@ -84,6 +87,7 @@ namespace WTF {
         bool contains(RawKeyType) const;
         MappedType get(const KeyType&) const;
         MappedType get(RawKeyType) const;
+        MappedType inlineGet(RawKeyType) const;
 
         // replaces value but not key if key is already present
         // return value is a pair of the iterator to the key location, 
@@ -108,56 +112,16 @@ namespace WTF {
     private:
         pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
         pair<iterator, bool> inlineAdd(RawKeyType, const MappedType&);
-        void refAll();
-        void derefAll();
 
         HashTableType m_impl;
     };
     
-    template<typename T, typename U, typename V, typename W, typename X>
-    inline void HashMap<RefPtr<T>, U, V, W, X>::refAll()
-    {
-        HashTableRefCounter<HashTableType, ValueTraits>::refAll(m_impl);
-    }
-
-    template<typename T, typename U, typename V, typename W, typename X>
-    inline void HashMap<RefPtr<T>, U, V, W, X>::derefAll()
-    {
-        HashTableRefCounter<HashTableType, ValueTraits>::derefAll(m_impl);
-    }
-
-    template<typename T, typename U, typename V, typename W, typename X>
-    inline HashMap<RefPtr<T>, U, V, W, X>::HashMap()
-    {
-    }
-
-    template<typename T, typename U, typename V, typename W, typename X>
-    inline HashMap<RefPtr<T>, U, V, W, X>::HashMap(const HashMap& other)
-        : m_impl(other.m_impl)
-    {
-        refAll();
-    }
-
-    template<typename T, typename U, typename V, typename W, typename X>
-    inline HashMap<RefPtr<T>, U, V, W, X>& HashMap<RefPtr<T>, U, V, W, X>::operator=(const HashMap& other)
-    {
-        HashMap tmp(other);
-        swap(tmp); 
-        return *this;
-    }
-
     template<typename T, typename U, typename V, typename W, typename X>
     inline void HashMap<RefPtr<T>, U, V, W, X>::swap(HashMap& other)
     {
         m_impl.swap(other.m_impl); 
     }
 
-    template<typename T, typename U, typename V, typename W, typename X>
-    inline HashMap<RefPtr<T>, U, V, W, X>::~HashMap()
-    {
-        derefAll();
-    }
-
     template<typename T, typename U, typename V, typename W, typename X>
     inline int HashMap<RefPtr<T>, U, V, W, X>::size() const
     {
@@ -203,45 +167,44 @@ namespace WTF {
     template<typename T, typename U, typename V, typename W, typename X>
     inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key)
     {
-        return m_impl.find(*(const KeyStorageType*)&key);
+        return m_impl.find(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
     inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key)
     {
-        return m_impl.find(*(const KeyStorageType*)&key);
+        return m_impl.template find<RawKeyType, RawKeyTranslator>(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
     inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) const
     {
-        return m_impl.find(*(const KeyStorageType*)&key);
+        return m_impl.find(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
     inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) const
     {
-        return m_impl.find(*(const KeyStorageType*)&key);
+        return m_impl.template find<RawKeyType, RawKeyTranslator>(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
     inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(const KeyType& key) const
     {
-        return m_impl.contains(*(const KeyStorageType*)&key);
+        return m_impl.contains(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
     inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(RawKeyType key) const
     {
-        return m_impl.contains(*(const KeyStorageType*)&key);
+        return m_impl.template contains<RawKeyType, RawKeyTranslator>(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
     inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
     HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped) 
     {
-        const bool canReplaceDeletedKey = !KeyTraits::needsDestruction || KeyStorageTraits::needsDestruction;
-        typedef HashMapTranslator<canReplaceDeletedKey, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> TranslatorType;
+        typedef HashMapTranslator<ValueType, ValueTraits, HashFunctions> TranslatorType;
         return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped);
     }
 
@@ -249,7 +212,7 @@ namespace WTF {
     inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
     HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(RawKeyType key, const MappedType& mapped) 
     {
-        return inlineAdd(*(const KeyType*)&key, mapped);
+        return m_impl.template add<RawKeyType, MappedType, RawKeyTranslator>(key, mapped);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
@@ -257,9 +220,10 @@ namespace WTF {
     HashMap<RefPtr<T>, U, V, W, X>::set(const KeyType& key, const MappedType& mapped) 
     {
         pair<iterator, bool> result = inlineAdd(key, mapped);
-        if (!result.second)
+        if (!result.second) {
             // add call above didn't change anything, so set the mapped value
             result.first->second = mapped;
+        }
         return result;
     }
 
@@ -268,9 +232,10 @@ namespace WTF {
     HashMap<RefPtr<T>, U, V, W, X>::set(RawKeyType key, const MappedType& mapped) 
     {
         pair<iterator, bool> result = inlineAdd(key, mapped);
-        if (!result.second)
+        if (!result.second) {
             // add call above didn't change anything, so set the mapped value
             result.first->second = mapped;
+        }
         return result;
     }
 
@@ -292,24 +257,27 @@ namespace WTF {
     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
     HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(const KeyType& key) const
     {
-        if (m_impl.isEmpty())
-            return MappedTraits::emptyValue();
-        ValueStorageType* entry = const_cast<HashTableType&>(m_impl).lookup(*(const KeyStorageType*)&key);
+        ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
         if (!entry)
             return MappedTraits::emptyValue();
-        return ((ValueType *)entry)->second;
+        return entry->second;
     }
 
     template<typename T, typename U, typename V, typename W, typename MappedTraits>
     typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
-    HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
+    inline HashMap<RefPtr<T>, U, V, W, MappedTraits>::inlineGet(RawKeyType key) const
     {
-        if (m_impl.isEmpty())
-            return MappedTraits::emptyValue();
-        ValueStorageType* entry = const_cast<HashTableType&>(m_impl).lookup(*(const KeyStorageType*)&key);
+        ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<RawKeyType, RawKeyTranslator>(key);
         if (!entry)
             return MappedTraits::emptyValue();
-        return ((ValueType *)entry)->second;
+        return entry->second;
+    }
+
+    template<typename T, typename U, typename V, typename W, typename MappedTraits>
+    typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
+    HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
+    {
+        return inlineGet(key);
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
@@ -317,8 +285,7 @@ namespace WTF {
     {
         if (it.m_impl == m_impl.end())
             return;
-        m_impl.checkTableConsistency();
-        RefCounter<ValueTraits, ValueStorageTraits>::deref(*it.m_impl);
+        m_impl.internalCheckTableConsistency();
         m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
     }
 
@@ -337,7 +304,6 @@ namespace WTF {
     template<typename T, typename U, typename V, typename W, typename X>
     inline void HashMap<RefPtr<T>, U, V, W, X>::clear()
     {
-        derefAll();
         m_impl.clear();
     }