1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef GrHashMapWithCache_DEFINED 9cb93a386Sopenharmony_ci#define GrHashMapWithCache_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/private/SkChecksum.h" 12cb93a386Sopenharmony_ci#include "include/private/SkNoncopyable.h" 13cb93a386Sopenharmony_ci#include "include/private/SkTHash.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci// Cheaper than SkGoodHash and good enough for UniqueID tables. 16cb93a386Sopenharmony_cistruct GrCheapHash { 17cb93a386Sopenharmony_ci uint32_t operator()(uint32_t val) { 18cb93a386Sopenharmony_ci return SkChecksum::CheapMix(val); 19cb93a386Sopenharmony_ci } 20cb93a386Sopenharmony_ci}; 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci/** A hash map that caches the most recently accessed entry. 23cb93a386Sopenharmony_ci The API is a subset of SkHashMap, and you must provide a 24cb93a386Sopenharmony_ci sentinel key that will never be present, such as SK_InvalidUniqueID. 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci KeyTraits must have: 27cb93a386Sopenharmony_ci - static K GetInvalidKey() 28cb93a386Sopenharmony_ci*/ 29cb93a386Sopenharmony_citemplate <typename K, typename V, typename KeyTraits, typename HashT = SkGoodHash> 30cb93a386Sopenharmony_ciclass GrHashMapWithCache : public SkNoncopyable { 31cb93a386Sopenharmony_cipublic: 32cb93a386Sopenharmony_ci // How many key/value pairs are in the table? 33cb93a386Sopenharmony_ci int count() const { return fMap.count(); } 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci // Approximately how many bytes of memory do we use beyond sizeof(*this)? 36cb93a386Sopenharmony_ci size_t approxBytesUsed() const { return fMap.approxBytesUsed(); } 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci // N.B. The pointers returned by set() and find() are valid only until the next call to set(). 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci // If there is key/value entry in the table with this key, return a pointer to the value. 41cb93a386Sopenharmony_ci // If not, return null. 42cb93a386Sopenharmony_ci const V* find(const K& key) const { 43cb93a386Sopenharmony_ci if (key != fLastKey) { 44cb93a386Sopenharmony_ci fLastKey = key; 45cb93a386Sopenharmony_ci fLastValue = fMap.find(key); 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci return fLastValue; 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci // Set key to val in the map, replacing any previous value with the same key. 51cb93a386Sopenharmony_ci // We copy both key and val, and return a pointer to the value copy now in the map. 52cb93a386Sopenharmony_ci const V* set(K key, V val) { 53cb93a386Sopenharmony_ci if (fLastValue && key == fLastKey) { 54cb93a386Sopenharmony_ci *fLastValue = std::move(val); 55cb93a386Sopenharmony_ci } else { 56cb93a386Sopenharmony_ci fLastKey = key; 57cb93a386Sopenharmony_ci fLastValue = fMap.set(std::move(key), std::move(val)); 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci return fLastValue; 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci // Remove the key/value entry in the table with this key. 63cb93a386Sopenharmony_ci void remove(K key) { 64cb93a386Sopenharmony_ci // Match SkTHashMap requirement. The caller can find() if they're unsure. 65cb93a386Sopenharmony_ci SkASSERT(fMap.find(fLastKey)); 66cb93a386Sopenharmony_ci fLastKey = std::move(key); 67cb93a386Sopenharmony_ci fLastValue = nullptr; 68cb93a386Sopenharmony_ci fMap.remove(fLastKey); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci // Clear the map. 72cb93a386Sopenharmony_ci void reset() { 73cb93a386Sopenharmony_ci fLastKey = KeyTraits::GetInvalidKey(); 74cb93a386Sopenharmony_ci fLastValue = nullptr; 75cb93a386Sopenharmony_ci fMap.reset(); 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ciprivate: 79cb93a386Sopenharmony_ci SkTHashMap<K, V, HashT> fMap; 80cb93a386Sopenharmony_ci mutable K fLastKey = KeyTraits::GetInvalidKey(); 81cb93a386Sopenharmony_ci mutable V* fLastValue = nullptr; 82cb93a386Sopenharmony_ci}; 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci#endif 85