LCOV - code coverage report
Current view: top level - xpcom/ds - nsRefPtrHashtable.h (source / functions) Hit Total Coverage
Test: output.info Lines: 36 51 70.6 %
Date: 2017-07-14 16:53:18 Functions: 79 407 19.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef nsRefPtrHashtable_h__
       8             : #define nsRefPtrHashtable_h__
       9             : 
      10             : #include "nsBaseHashtable.h"
      11             : #include "nsHashKeys.h"
      12             : #include "nsAutoPtr.h"
      13             : 
      14             : /**
      15             :  * templated hashtable class maps keys to reference pointers.
      16             :  * See nsBaseHashtable for complete declaration.
      17             :  * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
      18             :  *   for a complete specification.
      19             :  * @param PtrType the reference-type being wrapped
      20             :  * @see nsDataHashtable, nsClassHashtable
      21             :  */
      22             : template<class KeyClass, class PtrType>
      23        1704 : class nsRefPtrHashtable
      24             :   : public nsBaseHashtable<KeyClass, RefPtr<PtrType>, PtrType*>
      25             : {
      26             : public:
      27             :   typedef typename KeyClass::KeyType KeyType;
      28             :   typedef PtrType* UserDataType;
      29             :   typedef nsBaseHashtable<KeyClass, RefPtr<PtrType>, PtrType*> base_type;
      30             : 
      31        2154 :   nsRefPtrHashtable() {}
      32          13 :   explicit nsRefPtrHashtable(uint32_t aInitLength)
      33          13 :     : nsBaseHashtable<KeyClass, RefPtr<PtrType>, PtrType*>(aInitLength)
      34             :   {
      35          13 :   }
      36             : 
      37             :   /**
      38             :    * @copydoc nsBaseHashtable::Get
      39             :    * @param aData This is an XPCOM getter, so aData is already_addrefed.
      40             :    *   If the key doesn't exist, aData will be set to nullptr.
      41             :    */
      42             :   bool Get(KeyType aKey, UserDataType* aData) const;
      43             : 
      44             :   /**
      45             :    * Gets a weak reference to the hashtable entry.
      46             :    * @param aFound If not nullptr, will be set to true if the entry is found,
      47             :    *               to false otherwise.
      48             :    * @return The entry, or nullptr if not found. Do not release this pointer!
      49             :    */
      50             :   PtrType* GetWeak(KeyType aKey, bool* aFound = nullptr) const;
      51             : 
      52             :   // Overload Put, rather than overriding it.
      53             :   using base_type::Put;
      54             : 
      55             :   void Put(KeyType aKey, already_AddRefed<PtrType> aData);
      56             : 
      57             :   MOZ_MUST_USE bool Put(KeyType aKey, already_AddRefed<PtrType> aData,
      58             :                         const mozilla::fallible_t&);
      59             : 
      60             :   /**
      61             :    * Remove the entry associated with aKey (if any), optionally _moving_ its
      62             :    * current value into *aData, thereby avoiding calls to AddRef and Release.
      63             :    * Return true if found.
      64             :    * @param aKey the key to remove from the hashtable
      65             :    * @param aData where to move the value (if non-null).  If an entry is not
      66             :    *              found it will be set to nullptr.
      67             :    * @return true if an entry for aKey was found (and removed)
      68             :    */
      69             :   inline bool Remove(KeyType aKey, UserDataType* aData = nullptr);
      70             : };
      71             : 
      72             : template<typename K, typename T>
      73             : inline void
      74           0 : ImplCycleCollectionUnlink(nsRefPtrHashtable<K, T>& aField)
      75             : {
      76           0 :   aField.Clear();
      77           0 : }
      78             : 
      79             : template<typename K, typename T>
      80             : inline void
      81          17 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
      82             :                             nsRefPtrHashtable<K, T>& aField,
      83             :                             const char* aName,
      84             :                             uint32_t aFlags = 0)
      85             : {
      86          17 :   for (auto iter = aField.ConstIter(); !iter.Done(); iter.Next()) {
      87           0 :     CycleCollectionNoteChild(aCallback, iter.UserData(), aName, aFlags);
      88             :   }
      89          17 : }
      90             : 
      91             : //
      92             : // nsRefPtrHashtable definitions
      93             : //
      94             : 
      95             : template<class KeyClass, class PtrType>
      96             : bool
      97        4395 : nsRefPtrHashtable<KeyClass, PtrType>::Get(KeyType aKey,
      98             :                                           UserDataType* aRefPtr) const
      99             : {
     100        4395 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
     101             : 
     102        4395 :   if (ent) {
     103        2016 :     if (aRefPtr) {
     104        2016 :       *aRefPtr = ent->mData;
     105             : 
     106        2016 :       NS_IF_ADDREF(*aRefPtr);
     107             :     }
     108             : 
     109        2016 :     return true;
     110             :   }
     111             : 
     112             :   // if the key doesn't exist, set *aRefPtr to null
     113             :   // so that it is a valid XPCOM getter
     114        2379 :   if (aRefPtr) {
     115        2379 :     *aRefPtr = nullptr;
     116             :   }
     117             : 
     118        2379 :   return false;
     119             : }
     120             : 
     121             : template<class KeyClass, class PtrType>
     122             : PtrType*
     123        2579 : nsRefPtrHashtable<KeyClass, PtrType>::GetWeak(KeyType aKey, bool* aFound) const
     124             : {
     125        2579 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
     126             : 
     127        2579 :   if (ent) {
     128        1609 :     if (aFound) {
     129         141 :       *aFound = true;
     130             :     }
     131             : 
     132        1609 :     return ent->mData;
     133             :   }
     134             : 
     135             :   // Key does not exist, return nullptr and set aFound to false
     136         970 :   if (aFound) {
     137           0 :     *aFound = false;
     138             :   }
     139             : 
     140         970 :   return nullptr;
     141             : }
     142             : 
     143             : template<class KeyClass, class PtrType>
     144             : void
     145           0 : nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey,
     146             :                                           already_AddRefed<PtrType> aData)
     147             : {
     148           0 :   if (!Put(aKey, mozilla::Move(aData), mozilla::fallible)) {
     149           0 :     NS_ABORT_OOM(this->mTable.EntrySize() * this->mTable.EntryCount());
     150             :   }
     151           0 : }
     152             : 
     153             : template<class KeyClass, class PtrType>
     154             : bool
     155           0 : nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey,
     156             :                                           already_AddRefed<PtrType> aData,
     157             :                                           const mozilla::fallible_t&)
     158             : {
     159           0 :   typename base_type::EntryType* ent = this->PutEntry(aKey, mozilla::fallible);
     160             : 
     161           0 :   if (!ent) {
     162           0 :     return false;
     163             :   }
     164             : 
     165           0 :   ent->mData = aData;
     166             : 
     167           0 :   return true;
     168             : }
     169             : 
     170             : template<class KeyClass, class PtrType>
     171             : bool
     172          56 : nsRefPtrHashtable<KeyClass, PtrType>::Remove(KeyType aKey,
     173             :                                              UserDataType* aRefPtr)
     174             : {
     175          56 :   typename base_type::EntryType* ent = this->GetEntry(aKey);
     176             : 
     177          56 :   if (ent) {
     178          49 :     if (aRefPtr) {
     179          26 :       ent->mData.forget(aRefPtr);
     180             :     }
     181          49 :     this->RemoveEntry(ent);
     182          49 :     return true;
     183             :   }
     184             : 
     185           7 :   if (aRefPtr) {
     186           7 :     *aRefPtr = nullptr;
     187             :   }
     188           7 :   return false;
     189             : }
     190             : 
     191             : #endif // nsRefPtrHashtable_h__

Generated by: LCOV version 1.13