gfx/skia/trunk/src/gpu/GrTHashTable.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.

     2 /*
     3  * Copyright 2010 Google Inc.
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    11 #ifndef GrTHashTable_DEFINED
    12 #define GrTHashTable_DEFINED
    14 #include "GrTypes.h"
    15 #include "SkTDArray.h"
    17 /**
    18  *  Key needs
    19  *      static bool Equals(const Entry&, const Key&);
    20  *      static bool LessThan(const Entry&, const Key&);
    21  *      static bool Equals(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called
    22  *      static bool LessThan(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called
    23  *      uint32_t getHash() const;
    24  *
    25  *  Allows duplicate key entries but on find you may get
    26  *  any of the duplicate entries returned.
    27  */
    28 template <typename T, typename Key, size_t kHashBits> class GrTHashTable {
    29 public:
    30     GrTHashTable() { this->clearHash(); }
    31     ~GrTHashTable() {}
    33     int count() const { return fSorted.count(); }
    35     struct Any {
    36         // Return the first resource that matches the key.
    37         bool operator()(const T*) const { return true; }
    38     };
    40     T* find(const Key& key) const { return this->find(key, Any()); }
    41     template <typename Filter> T* find(const Key&, Filter filter) const;
    43     // return true if key was unique when inserted.
    44     bool insert(const Key&, T*);
    45     void remove(const Key&, const T*);
    47     void deleteAll();
    49 #ifdef SK_DEBUG
    50     void validate() const;
    51     bool contains(T*) const;
    52 #endif
    54     // testing
    55     const SkTDArray<T*>& getArray() const { return fSorted; }
    56     SkTDArray<T*>& getArray() { return fSorted; }
    57 private:
    58     void clearHash() { sk_bzero(fHash, sizeof(fHash)); }
    60     enum {
    61         kHashCount = 1 << kHashBits,
    62         kHashMask  = kHashCount - 1
    63     };
    64     static unsigned hash2Index(uint32_t hash) {
    65         hash ^= hash >> 16;
    66         if (kHashBits <= 8) {
    67             hash ^= hash >> 8;
    68         }
    69         return hash & kHashMask;
    70     }
    72     mutable T* fHash[kHashCount];
    73     SkTDArray<T*> fSorted;
    75     // search fSorted, and return the found index, or ~index of where it
    76     // should be inserted
    77     int searchArray(const Key&) const;
    78 };
    80 ///////////////////////////////////////////////////////////////////////////////
    82 template <typename T, typename Key, size_t kHashBits>
    83 int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const {
    84     int count = fSorted.count();
    85     if (0 == count) {
    86         // we should insert it at 0
    87         return ~0;
    88     }
    90     const T* const* array = fSorted.begin();
    91     int high = count - 1;
    92     int low = 0;
    93     while (high > low) {
    94         int index = (low + high) >> 1;
    95         if (Key::LessThan(*array[index], key)) {
    96             low = index + 1;
    97         } else {
    98             high = index;
    99         }
   100     }
   102     // check if we found it
   103     if (Key::Equals(*array[high], key)) {
   104         // above search should have found the first occurrence if there
   105         // are multiple.
   106         SkASSERT(0 == high || Key::LessThan(*array[high - 1], key));
   107         return high;
   108     }
   110     // now return the ~ of where we should insert it
   111     if (Key::LessThan(*array[high], key)) {
   112         high += 1;
   113     }
   114     return ~high;
   115 }
   117 template <typename T, typename Key, size_t kHashBits>
   118 template <typename Filter>
   119 T* GrTHashTable<T, Key, kHashBits>::find(const Key& key, Filter filter) const {
   121     int hashIndex = hash2Index(key.getHash());
   122     T* elem = fHash[hashIndex];
   124     if (NULL != elem && Key::Equals(*elem, key) && filter(elem)) {
   125         return elem;
   126     }
   128     // bsearch for the key in our sorted array
   129     int index = this->searchArray(key);
   130     if (index < 0) {
   131         return NULL;
   132     }
   134     const T* const* array = fSorted.begin();
   136     // above search should have found the first occurrence if there
   137     // are multiple.
   138     SkASSERT(0 == index || Key::LessThan(*array[index - 1], key));
   140     for ( ; index < count() && Key::Equals(*array[index], key); ++index) {
   141         if (filter(fSorted[index])) {
   142             // update the hash
   143             fHash[hashIndex] = fSorted[index];
   144             return fSorted[index];
   145         }
   146     }
   148     return NULL;
   149 }
   151 template <typename T, typename Key, size_t kHashBits>
   152 bool GrTHashTable<T, Key, kHashBits>::insert(const Key& key, T* elem) {
   153     int index = this->searchArray(key);
   154     bool first = index < 0;
   155     if (first) {
   156         // turn it into the actual index
   157         index = ~index;
   158     }
   159     // add it to our array
   160     *fSorted.insert(index) = elem;
   161     // update our hash table (overwrites any dupe's position in the hash)
   162     fHash[hash2Index(key.getHash())] = elem;
   163     return first;
   164 }
   166 template <typename T, typename Key, size_t kHashBits>
   167 void GrTHashTable<T, Key, kHashBits>::remove(const Key& key, const T* elem) {
   168     int index = hash2Index(key.getHash());
   169     if (fHash[index] == elem) {
   170         fHash[index] = NULL;
   171     }
   173     // remove from our sorted array
   174     index = this->searchArray(key);
   175     SkASSERT(index >= 0);
   176     // if there are multiple matches searchArray will give us the first match
   177     // march forward until we find elem.
   178     while (elem != fSorted[index]) {
   179         ++index;
   180         SkASSERT(index < fSorted.count());
   181     }
   182     SkASSERT(elem == fSorted[index]);
   183     fSorted.remove(index);
   184 }
   186 template <typename T, typename Key, size_t kHashBits>
   187 void GrTHashTable<T, Key, kHashBits>::deleteAll() {
   188     fSorted.deleteAll();
   189     this->clearHash();
   190 }
   192 #ifdef SK_DEBUG
   193 template <typename T, typename Key, size_t kHashBits>
   194 void GrTHashTable<T, Key, kHashBits>::validate() const {
   195     int count = fSorted.count();
   196     for (int i = 1; i < count; i++) {
   197         SkASSERT(Key::LessThan(*fSorted[i - 1], *fSorted[i]) ||
   198                  Key::Equals(*fSorted[i - 1], *fSorted[i]));
   199     }
   200 }
   202 template <typename T, typename Key, size_t kHashBits>
   203 bool GrTHashTable<T, Key, kHashBits>::contains(T* elem) const {
   204     int index = fSorted.find(elem);
   205     return index >= 0;
   206 }
   208 #endif
   210 #endif

mercurial