LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkTMultiMap.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 72 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef SkTMultiMap_DEFINED
       9             : #define SkTMultiMap_DEFINED
      10             : 
      11             : #include "GrTypes.h"
      12             : #include "SkTDynamicHash.h"
      13             : 
      14             : /** A set that contains pointers to instances of T. Instances can be looked up with key Key.
      15             :  * Multiple (possibly same) values can have the same key.
      16             :  */
      17             : template <typename T,
      18             :           typename Key,
      19             :           typename HashTraits=T>
      20             : class SkTMultiMap {
      21             :     struct ValueList {
      22           0 :         explicit ValueList(T* value) : fValue(value), fNext(nullptr) {}
      23             : 
      24           0 :         static const Key& GetKey(const ValueList& e) { return HashTraits::GetKey(*e.fValue); }
      25           0 :         static uint32_t Hash(const Key& key) { return HashTraits::Hash(key); }
      26             :         T* fValue;
      27             :         ValueList* fNext;
      28             :     };
      29             : public:
      30           0 :     SkTMultiMap() : fCount(0) {}
      31             : 
      32           0 :     ~SkTMultiMap() {
      33           0 :         SkASSERT(fCount == 0);
      34           0 :         SkASSERT(fHash.count() == 0);
      35           0 :     }
      36             : 
      37           0 :     void insert(const Key& key, T* value) {
      38           0 :         ValueList* list = fHash.find(key);
      39           0 :         if (list) {
      40             :             // The new ValueList entry is inserted as the second element in the
      41             :             // linked list, and it will contain the value of the first element.
      42           0 :             ValueList* newEntry = new ValueList(list->fValue);
      43           0 :             newEntry->fNext = list->fNext;
      44             :             // The existing first ValueList entry is updated to contain the
      45             :             // inserted value.
      46           0 :             list->fNext = newEntry;
      47           0 :             list->fValue = value;
      48             :         } else {
      49           0 :             fHash.add(new ValueList(value));
      50             :         }
      51             : 
      52           0 :         ++fCount;
      53           0 :     }
      54             : 
      55           0 :     void remove(const Key& key, const T* value) {
      56           0 :         ValueList* list = fHash.find(key);
      57             :         // Since we expect the caller to be fully aware of what is stored, just
      58             :         // assert that the caller removes an existing value.
      59           0 :         SkASSERT(list);
      60           0 :         ValueList* prev = nullptr;
      61           0 :         while (list->fValue != value) {
      62           0 :             prev = list;
      63           0 :             list = list->fNext;
      64             :         }
      65             : 
      66           0 :         if (list->fNext) {
      67           0 :             ValueList* next = list->fNext;
      68           0 :             list->fValue = next->fValue;
      69           0 :             list->fNext = next->fNext;
      70             :             delete next;
      71           0 :         } else if (prev) {
      72           0 :             prev->fNext = nullptr;
      73             :             delete list;
      74             :         } else {
      75           0 :             fHash.remove(key);
      76             :             delete list;
      77             :         }
      78             : 
      79           0 :         --fCount;
      80           0 :     }
      81             : 
      82             :     T* find(const Key& key) const {
      83             :         ValueList* list = fHash.find(key);
      84             :         if (list) {
      85             :             return list->fValue;
      86             :         }
      87             :         return nullptr;
      88             :     }
      89             : 
      90             :     template<class FindPredicate>
      91           0 :     T* find(const Key& key, const FindPredicate f) {
      92           0 :         ValueList* list = fHash.find(key);
      93           0 :         while (list) {
      94           0 :             if (f(list->fValue)){
      95           0 :                 return list->fValue;
      96             :             }
      97           0 :             list = list->fNext;
      98             :         }
      99           0 :         return nullptr;
     100             :     }
     101             : 
     102           0 :     int count() const { return fCount; }
     103             : 
     104             : #ifdef SK_DEBUG
     105             :     class ConstIter {
     106             :     public:
     107           0 :         explicit ConstIter(const SkTMultiMap* mmap)
     108             :             : fIter(&(mmap->fHash))
     109           0 :             , fList(nullptr) {
     110           0 :             if (!fIter.done()) {
     111           0 :                 fList = &(*fIter);
     112             :             }
     113           0 :         }
     114             : 
     115           0 :         bool done() const {
     116           0 :             return fIter.done();
     117             :         }
     118             : 
     119           0 :         const T* operator*() {
     120           0 :             SkASSERT(fList);
     121           0 :             return fList->fValue;
     122             :         }
     123             : 
     124           0 :         void operator++() {
     125           0 :             if (fList) {
     126           0 :                 fList = fList->fNext;
     127             :             }
     128           0 :             if (!fList) {
     129           0 :                 ++fIter;
     130           0 :                 if (!fIter.done()) {
     131           0 :                     fList = &(*fIter);
     132             :                 }
     133             :             }
     134           0 :         }
     135             : 
     136             :     private:
     137             :         typename SkTDynamicHash<ValueList, Key>::ConstIter fIter;
     138             :         const ValueList* fList;
     139             :     };
     140             : 
     141           0 :     bool has(const T* value, const Key& key) const {
     142           0 :         for (ValueList* list = fHash.find(key); list; list = list->fNext) {
     143           0 :             if (list->fValue == value) {
     144           0 :                 return true;
     145             :             }
     146             :         }
     147           0 :         return false;
     148             :     }
     149             : 
     150             :     // This is not particularly fast and only used for validation, so debug only.
     151           0 :     int countForKey(const Key& key) const {
     152           0 :         int count = 0;
     153           0 :         ValueList* list = fHash.find(key);
     154           0 :         while (list) {
     155           0 :             list = list->fNext;
     156           0 :             ++count;
     157             :         }
     158           0 :         return count;
     159             :     }
     160             : #endif
     161             : 
     162             : private:
     163             :     SkTDynamicHash<ValueList, Key> fHash;
     164             :     int fCount;
     165             : };
     166             : 
     167             : #endif

Generated by: LCOV version 1.13