7#ifndef PXR_IMAGING_HD_INSTANCE_REGISTRY_H
8#define PXR_IMAGING_HD_INSTANCE_REGISTRY_H
11#include "pxr/imaging/hd/api.h"
12#include "pxr/imaging/hd/version.h"
13#include "pxr/imaging/hd/perfLog.h"
14#include "pxr/imaging/hf/perfLog.h"
16#include <tbb/concurrent_unordered_map.h>
21PXR_NAMESPACE_OPEN_SCOPE
42template <
typename VALUE>
45 typedef uint64_t KeyType;
46 typedef VALUE ValueType;
51 ValueHolder(ValueType
const & value = ValueType())
55 void ResetRecycleCounter() {
62 typedef tbb::concurrent_unordered_map<KeyType, ValueHolder> Dictionary;
64 typedef std::mutex RegistryMutex;
65 typedef std::unique_lock<RegistryMutex> RegistryLock;
72 ValueType
const &value,
73 RegistryLock &®istryLock,
74 Dictionary *container)
77 , _registryLock(
std::move(registryLock))
78 , _container(container)
79 , _isFirstInstance(!bool(_value))
90 , _isFirstInstance(!bool(_value))
94 KeyType
const &
GetKey()
const {
return _key; }
97 ValueType
const &
GetValue()
const {
return _value; }
101 if (_container) (*_container)[_key] = ValueHolder(value);
107 return _isFirstInstance;
113 RegistryLock _registryLock;
114 Dictionary *_container;
115 bool _isFirstInstance;
128template <
typename VALUE>
138 : _dictionary(other._dictionary)
144 typename InstanceType::KeyType
const &key);
149 typename InstanceType::KeyType
const &key,
bool *found);
164 template <
typename Callback>
173 size_t size()
const {
return _dictionary.size(); }
178 template <
typename T>
179 static bool _IsUnique(std::shared_ptr<T>
const &value) {
180 return value.unique();
183 typename InstanceType::Dictionary _dictionary;
184 typename InstanceType::RegistryMutex _registryMutex;
192template <
typename VALUE>
195 typename HdInstance<VALUE>::KeyType
const &key)
198 HF_MALLOC_TAG_FUNCTION();
202 typename InstanceType::RegistryLock lock(_registryMutex);
204 typename InstanceType::Dictionary::iterator it = _dictionary.find(key);
205 if (it == _dictionary.end()) {
207 it = _dictionary.insert(
208 std::make_pair(key,
typename InstanceType::ValueHolder())).first;
211 it->second.ResetRecycleCounter();
212 return InstanceType(key, it->second.value, std::move(lock), &_dictionary);
215template <
typename VALUE>
218 typename HdInstance<VALUE>::KeyType
const &key,
bool *found)
221 HF_MALLOC_TAG_FUNCTION();
225 typename InstanceType::RegistryLock lock(_registryMutex);
227 typename InstanceType::Dictionary::iterator it = _dictionary.find(key);
228 if (it == _dictionary.end()) {
230 return InstanceType(key, VALUE(), std::move(lock),
nullptr);
233 it->second.ResetRecycleCounter();
234 return InstanceType(key, it->second.value,std::move(lock),&_dictionary);
238template <
typename VALUE>
243 return GarbageCollect([](
void*){}, recycleCount);
246template <
typename VALUE>
247template <
typename Callback>
252 HF_MALLOC_TAG_FUNCTION();
255 if (recycleCount < 0) {
256 return _dictionary.size();
259 size_t inUseCount = 0;
260 for (
typename InstanceType::Dictionary::iterator it = _dictionary.begin();
261 it != _dictionary.end();) {
264 bool isUnique = _IsUnique(it->second.value);
265 if (isUnique && (++it->second.recycleCounter > recycleCount)) {
266 std::forward<Callback>(callback)(it->second.value.get());
267 it = _dictionary.unsafe_erase(it);
276template <
typename VALUE>
281 HF_MALLOC_TAG_FUNCTION();
287PXR_NAMESPACE_CLOSE_SCOPE
This class is used as an interface to a shared instance in HdInstanceRegistry.
bool IsFirstInstance() const
Returns true if the value has not been initialized.
void SetValue(ValueType const &value)
Update the value in dictionary indexed by the key.
ValueType const & GetValue() const
Returns the value.
HdInstance(KeyType const &key, ValueType const &value, RegistryLock &®istryLock, Dictionary *container)
Construct an instance holding a registry lock, representing a value held in a registry container.
HdInstance(KeyType const &key)
Construct an instance with no lock or registry container.
KeyType const & GetKey() const
Returns the key.
HdInstanceRegistry is a dictionary container of HdInstance.
InstanceType GetInstance(typename InstanceType::KeyType const &key)
Returns a shared instance for given key.
size_t GarbageCollect(int recycleCount=0)
Removes unreferenced entries and returns the count of remaining entries.
InstanceType::Dictionary::const_iterator const_iterator
Returns a const iterator being/end of dictionary.
InstanceType FindInstance(typename InstanceType::KeyType const &key, bool *found)
Returns a shared instance for a given key only if the key exists in the dictionary.
size_t GarbageCollect(Callback &&callback, int recycleCount=0)
Removes unreferenced entries and returns the count of remaining entries.
HdInstanceRegistry(const HdInstanceRegistry &other)
Copy constructor.