xpcom/glue/nsBaseHashtable.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsBaseHashtable_h__
     7 #define nsBaseHashtable_h__
     9 #include "mozilla/MemoryReporting.h"
    10 #include "mozilla/Move.h"
    11 #include "nsTHashtable.h"
    12 #include "prlock.h"
    13 #include "nsDebug.h"
    15 template<class KeyClass,class DataType,class UserDataType>
    16 class nsBaseHashtable; // forward declaration
    18 /**
    19  * the private nsTHashtable::EntryType class used by nsBaseHashtable
    20  * @see nsTHashtable for the specification of this class
    21  * @see nsBaseHashtable for template parameters
    22  */
    23 template<class KeyClass,class DataType>
    24 class nsBaseHashtableET : public KeyClass
    25 {
    26 public:
    27   DataType mData;
    28   friend class nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >;
    30 private:
    31   typedef typename KeyClass::KeyType KeyType;
    32   typedef typename KeyClass::KeyTypePointer KeyTypePointer;
    34   nsBaseHashtableET(KeyTypePointer aKey);
    35   nsBaseHashtableET(nsBaseHashtableET<KeyClass,DataType>&& toMove);
    36   ~nsBaseHashtableET();
    37 };
    39 /**
    40  * templated hashtable for simple data types
    41  * This class manages simple data types that do not need construction or
    42  * destruction.
    43  *
    44  * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
    45  *   for a complete specification.
    46  * @param DataType the datatype stored in the hashtable,
    47  *   for example, uint32_t or nsCOMPtr.  If UserDataType is not the same,
    48  *   DataType must implicitly cast to UserDataType
    49  * @param UserDataType the user sees, for example uint32_t or nsISupports*
    50  */
    51 template<class KeyClass,class DataType,class UserDataType>
    52 class nsBaseHashtable :
    53   protected nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >
    54 {
    55   typedef mozilla::fallible_t fallible_t;
    57 public:
    58   typedef typename KeyClass::KeyType KeyType;
    59   typedef nsBaseHashtableET<KeyClass,DataType> EntryType;
    61   using nsTHashtable<EntryType>::Contains;
    63   nsBaseHashtable()
    64   {
    65   }
    66   explicit nsBaseHashtable(uint32_t aInitSize)
    67     : nsTHashtable<EntryType>(aInitSize)
    68   {
    69   }
    71   /**
    72    * Return the number of entries in the table.
    73    * @return    number of entries
    74    */
    75   uint32_t Count() const
    76   { return nsTHashtable<EntryType>::Count(); }
    78   /**
    79    * retrieve the value for a key.
    80    * @param aKey the key to retreive
    81    * @param pData data associated with this key will be placed at this
    82    *   pointer.  If you only need to check if the key exists, pData
    83    *   may be null.
    84    * @return true if the key exists. If key does not exist, pData is not
    85    *   modified.
    86    */
    87   bool Get(KeyType aKey, UserDataType* pData) const
    88   {
    89     EntryType* ent = this->GetEntry(aKey);
    91     if (!ent)
    92       return false;
    94     if (pData)
    95       *pData = ent->mData;
    97     return true;
    98   }
   100   /**
   101    * For pointer types, get the value, returning nullptr if the entry is not
   102    * present in the table.
   103    *
   104    * @param aKey the key to retrieve
   105    * @return The found value, or nullptr if no entry was found with the given key.
   106    * @note If nullptr values are stored in the table, it is not possible to
   107    *       distinguish between a nullptr value and a missing entry.
   108    */
   109   UserDataType Get(KeyType aKey) const
   110   {
   111     EntryType* ent = this->GetEntry(aKey);
   112     if (!ent)
   113       return 0;
   115     return ent->mData;
   116   }
   118   /**
   119    * put a new value for the associated key
   120    * @param aKey the key to put
   121    * @param aData the new data
   122    * @return always true, unless memory allocation failed
   123    */
   124   void Put(KeyType aKey, const UserDataType& aData)
   125   {
   126     if (!Put(aKey, aData, fallible_t()))
   127       NS_ABORT_OOM(this->mTable.entrySize * this->mTable.entryCount);
   128   }
   130   bool Put(KeyType aKey, const UserDataType& aData, const fallible_t&) NS_WARN_UNUSED_RESULT
   131   {
   132     EntryType* ent = this->PutEntry(aKey);
   134     if (!ent)
   135       return false;
   137     ent->mData = aData;
   139     return true;
   140   }
   142   /**
   143    * remove the data for the associated key
   144    * @param aKey the key to remove from the hashtable
   145    */
   146   void Remove(KeyType aKey) { this->RemoveEntry(aKey); }
   148   /**
   149    * function type provided by the application for enumeration.
   150    * @param aKey the key being enumerated
   151    * @param aData data being enumerated
   152    * @parm userArg passed unchanged from Enumerate
   153    * @return either
   154    *   @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink or
   155    *   @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
   156    */
   157   typedef PLDHashOperator
   158     (* EnumReadFunction)(KeyType      aKey,
   159                          UserDataType aData,
   160                          void*        userArg);
   162   /**
   163    * enumerate entries in the hashtable, without allowing changes
   164    * @param enumFunc enumeration callback
   165    * @param userArg passed unchanged to the EnumReadFunction
   166    */
   167   uint32_t EnumerateRead(EnumReadFunction enumFunc, void* userArg) const
   168   {
   169     NS_ASSERTION(this->mTable.entrySize,
   170                  "nsBaseHashtable was not initialized properly.");
   172     s_EnumReadArgs enumData = { enumFunc, userArg };
   173     return PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&this->mTable),
   174                                   s_EnumReadStub,
   175                                   &enumData);
   176   }
   178   /**
   179    * function type provided by the application for enumeration.
   180    * @param aKey the key being enumerated
   181    * @param aData Reference to data being enumerated, may be altered. e.g. for
   182    *        nsInterfaceHashtable this is an nsCOMPtr reference...
   183    * @parm userArg passed unchanged from Enumerate
   184    * @return bitflag combination of
   185    *   @link PLDHashOperator::PL_DHASH_REMOVE @endlink,
   186    *   @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or
   187    *   @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
   188    */
   189   typedef PLDHashOperator
   190     (* EnumFunction)(KeyType       aKey,
   191                      DataType&     aData,
   192                      void*         userArg);
   194   /**
   195    * enumerate entries in the hashtable, allowing changes. This
   196    * functions write-locks the hashtable.
   197    * @param enumFunc enumeration callback
   198    * @param userArg passed unchanged to the EnumFunction
   199    */
   200   uint32_t Enumerate(EnumFunction enumFunc, void* userArg)
   201   {
   202     NS_ASSERTION(this->mTable.entrySize,
   203                  "nsBaseHashtable was not initialized properly.");
   205     s_EnumArgs enumData = { enumFunc, userArg };
   206     return PL_DHashTableEnumerate(&this->mTable,
   207                                   s_EnumStub,
   208                                   &enumData);
   209   }
   211   /**
   212    * reset the hashtable, removing all entries
   213    */
   214   void Clear() { nsTHashtable<EntryType>::Clear(); }
   216   /**
   217    * client must provide a SizeOfEntryExcludingThisFun function for
   218    *   SizeOfExcludingThis.
   219    * @param     aKey the key being enumerated
   220    * @param     aData Reference to data being enumerated.
   221    * @param     mallocSizeOf the function used to measure heap-allocated blocks
   222    * @param     userArg passed unchanged from SizeOf{In,Ex}cludingThis
   223    * @return    summed size of the things pointed to by the entries
   224    */
   225   typedef size_t
   226     (* SizeOfEntryExcludingThisFun)(KeyType           aKey,
   227                                     const DataType    &aData,
   228                                     mozilla::MallocSizeOf mallocSizeOf,
   229                                     void*             userArg);
   231   /**
   232    * Measure the size of the table's entry storage and the table itself.
   233    * If |sizeOfEntryExcludingThis| is non-nullptr, measure the size of things
   234    * pointed to by entries.
   235    *
   236    * @param    sizeOfEntryExcludingThis
   237    *           the <code>SizeOfEntryExcludingThisFun</code> function to call
   238    * @param    mallocSizeOf the function used to meeasure heap-allocated blocks
   239    * @param    userArg a point to pass to the
   240    *           <code>SizeOfEntryExcludingThisFun</code> function
   241    * @return   the summed size of the entries, the table, and the table's storage
   242    */
   243   size_t SizeOfIncludingThis(SizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
   244                              mozilla::MallocSizeOf mallocSizeOf, void *userArg = nullptr)
   245   {
   246     return mallocSizeOf(this) + this->SizeOfExcludingThis(sizeOfEntryExcludingThis,
   247                                                           mallocSizeOf, userArg);
   248   }
   250   /**
   251    * Measure the size of the table's entry storage, and if
   252    * |sizeOfEntryExcludingThis| is non-nullptr, measure the size of things pointed
   253    * to by entries.
   254    * 
   255    * @param     sizeOfEntryExcludingThis the
   256    *            <code>SizeOfEntryExcludingThisFun</code> function to call
   257    * @param     mallocSizeOf the function used to measure heap-allocated blocks
   258    * @param     userArg a pointer to pass to the
   259    *            <code>SizeOfEntryExcludingThisFun</code> function
   260    * @return    the summed size of all the entries
   261    */
   262   size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
   263                              mozilla::MallocSizeOf mallocSizeOf, void *userArg = nullptr) const
   264   {
   265     if (sizeOfEntryExcludingThis) {
   266       s_SizeOfArgs args = { sizeOfEntryExcludingThis, userArg };
   267       return PL_DHashTableSizeOfExcludingThis(&this->mTable, s_SizeOfStub,
   268                                               mallocSizeOf, &args);
   269     }
   270     return PL_DHashTableSizeOfExcludingThis(&this->mTable, nullptr,
   271                                             mallocSizeOf);
   272   }
   274 #ifdef DEBUG
   275   using nsTHashtable<EntryType>::MarkImmutable;
   276 #endif
   278 protected:
   279   /**
   280    * used internally during EnumerateRead.  Allocated on the stack.
   281    * @param func the enumerator passed to EnumerateRead
   282    * @param userArg the userArg passed to EnumerateRead
   283    */
   284   struct s_EnumReadArgs
   285   {
   286     EnumReadFunction func;
   287     void* userArg;
   288   };
   290   static PLDHashOperator s_EnumReadStub(PLDHashTable    *table,
   291                                         PLDHashEntryHdr *hdr,
   292                                         uint32_t         number,
   293                                         void            *arg);
   295   struct s_EnumArgs
   296   {
   297     EnumFunction func;
   298     void* userArg;
   299   };
   301   static PLDHashOperator s_EnumStub(PLDHashTable      *table,
   302                                     PLDHashEntryHdr   *hdr,
   303                                     uint32_t           number,
   304                                     void              *arg);
   306   struct s_SizeOfArgs
   307   {
   308     SizeOfEntryExcludingThisFun func;
   309     void* userArg;
   310   };
   312   static size_t s_SizeOfStub(PLDHashEntryHdr *entry,
   313                              mozilla::MallocSizeOf mallocSizeOf,
   314                              void *arg);
   315 };
   317 class nsCycleCollectionTraversalCallback;
   319 struct MOZ_STACK_CLASS nsBaseHashtableCCTraversalData
   320 {
   321   nsBaseHashtableCCTraversalData(nsCycleCollectionTraversalCallback& aCallback,
   322                                  const char* aName,
   323                                  uint32_t aFlags)
   324   : mCallback(aCallback),
   325     mName(aName),
   326     mFlags(aFlags)
   327   {
   328   }
   330   nsCycleCollectionTraversalCallback& mCallback;
   331   const char* mName;
   332   uint32_t mFlags;
   334 };
   336 template <typename K, typename T>
   337 PLDHashOperator
   338 ImplCycleCollectionTraverse_EnumFunc(K aKey,
   339                                      T aData,
   340                                      void* aUserData)
   341 {
   342   nsBaseHashtableCCTraversalData* userData =
   343     static_cast<nsBaseHashtableCCTraversalData*>(aUserData);
   345   CycleCollectionNoteChild(userData->mCallback,
   346                            aData,
   347                            userData->mName,
   348                            userData->mFlags);
   349   return PL_DHASH_NEXT;
   350 }
   352 //
   353 // nsBaseHashtableET definitions
   354 //
   356 template<class KeyClass,class DataType>
   357 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET(KeyTypePointer aKey) :
   358   KeyClass(aKey)
   359 { }
   361 template<class KeyClass,class DataType>
   362 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET
   363   (nsBaseHashtableET<KeyClass,DataType>&& toMove) :
   364   KeyClass(mozilla::Move(toMove)),
   365   mData(mozilla::Move(toMove.mData))
   366 { }
   368 template<class KeyClass,class DataType>
   369 nsBaseHashtableET<KeyClass,DataType>::~nsBaseHashtableET()
   370 { }
   373 //
   374 // nsBaseHashtable definitions
   375 //
   377 template<class KeyClass,class DataType,class UserDataType>
   378 PLDHashOperator
   379 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub
   380   (PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number, void* arg)
   381 {
   382   EntryType* ent = static_cast<EntryType*>(hdr);
   383   s_EnumReadArgs* eargs = (s_EnumReadArgs*) arg;
   385   PLDHashOperator res = (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
   387   NS_ASSERTION( !(res & PL_DHASH_REMOVE ),
   388                 "PL_DHASH_REMOVE return during const enumeration; ignoring.");
   390   if (res & PL_DHASH_STOP)
   391     return PL_DHASH_STOP;
   393   return PL_DHASH_NEXT;
   394 }
   396 template<class KeyClass,class DataType,class UserDataType>
   397 PLDHashOperator
   398 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumStub
   399   (PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number, void* arg)
   400 {
   401   EntryType* ent = static_cast<EntryType*>(hdr);
   402   s_EnumArgs* eargs = (s_EnumArgs*) arg;
   404   return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
   405 }
   407 template<class KeyClass,class DataType,class UserDataType>
   408 size_t
   409 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_SizeOfStub
   410   (PLDHashEntryHdr *hdr, mozilla::MallocSizeOf mallocSizeOf, void *arg)
   411 {
   412   EntryType* ent = static_cast<EntryType*>(hdr);
   413   s_SizeOfArgs* eargs = static_cast<s_SizeOfArgs*>(arg);
   415   return (eargs->func)(ent->GetKey(), ent->mData, mallocSizeOf, eargs->userArg);
   416 }
   418 #endif // nsBaseHashtable_h__

mercurial