24 #ifndef PXR_IMAGING_HD_INSTANCE_REGISTRY_H
25 #define PXR_IMAGING_HD_INSTANCE_REGISTRY_H
28 #include "pxr/imaging/hd/api.h"
29 #include "pxr/imaging/hd/version.h"
30 #include "pxr/imaging/hd/perfLog.h"
31 #include "pxr/imaging/hf/perfLog.h"
33 #include <tbb/concurrent_unordered_map.h>
38 PXR_NAMESPACE_OPEN_SCOPE
59 template <
typename VALUE>
62 typedef uint64_t KeyType;
63 typedef VALUE ValueType;
68 ValueHolder(ValueType
const & value = ValueType())
72 void ResetRecycleCounter() {
79 typedef tbb::concurrent_unordered_map<KeyType, ValueHolder> Dictionary;
81 typedef std::mutex RegistryMutex;
82 typedef std::unique_lock<RegistryMutex> RegistryLock;
89 ValueType
const &value,
90 RegistryLock &®istryLock,
91 Dictionary *container)
94 , _registryLock(std::move(registryLock))
95 , _container(container)
96 , _isFirstInstance(!bool(_value))
104 , _value(ValueType())
106 , _container(nullptr)
107 , _isFirstInstance(!bool(_value))
111 KeyType
const &
GetKey()
const {
return _key; }
114 ValueType
const &
GetValue()
const {
return _value; }
118 if (_container) (*_container)[_key] = ValueHolder(value);
124 return _isFirstInstance;
130 RegistryLock _registryLock;
131 Dictionary *_container;
132 bool _isFirstInstance;
145 template <
typename VALUE>
155 : _dictionary(other._dictionary)
161 typename InstanceType::KeyType
const &key);
166 typename InstanceType::KeyType
const &key,
bool *found);
181 size_t size()
const {
return _dictionary.size(); }
186 template <
typename T>
187 static bool _IsUnique(std::shared_ptr<T>
const &value) {
188 return value.unique();
191 typename InstanceType::Dictionary _dictionary;
192 typename InstanceType::RegistryMutex _registryMutex;
200 template <
typename VALUE>
203 typename HdInstance<VALUE>::KeyType
const &key)
206 HF_MALLOC_TAG_FUNCTION();
210 typename InstanceType::RegistryLock lock(_registryMutex);
212 typename InstanceType::Dictionary::iterator it = _dictionary.find(key);
213 if (it == _dictionary.end()) {
215 it = _dictionary.insert(
216 std::make_pair(key,
typename InstanceType::ValueHolder())).first;
219 it->second.ResetRecycleCounter();
220 return InstanceType(key, it->second.value, std::move(lock), &_dictionary);
223 template <
typename VALUE>
226 typename HdInstance<VALUE>::KeyType
const &key,
bool *found)
229 HF_MALLOC_TAG_FUNCTION();
233 typename InstanceType::RegistryLock lock(_registryMutex);
235 typename InstanceType::Dictionary::iterator it = _dictionary.find(key);
236 if (it == _dictionary.end()) {
238 return InstanceType(key, VALUE(), std::move(lock),
nullptr);
241 it->second.ResetRecycleCounter();
242 return InstanceType(key, it->second.value,std::move(lock),&_dictionary);
246 template <
typename VALUE>
251 HF_MALLOC_TAG_FUNCTION();
254 if (recycleCount < 0) {
255 return _dictionary.size();
258 size_t inUseCount = 0;
259 for (
typename InstanceType::Dictionary::iterator it = _dictionary.begin();
260 it != _dictionary.end();) {
263 bool isUnique = _IsUnique(it->second.value);
264 if (isUnique && (++it->second.recycleCounter > recycleCount)) {
265 it = _dictionary.unsafe_erase(it);
274 template <
typename VALUE>
279 HF_MALLOC_TAG_FUNCTION();
285 PXR_NAMESPACE_CLOSE_SCOPE
287 #endif // PXR_IMAGING_HD_INSTANCE_REGISTRY_H
HdInstance(KeyType const &key)
Construct an instance with no lock or registry container.
bool IsFirstInstance() const
Returns true if the value has not been initialized.
InstanceType::Dictionary::const_iterator const_iterator
Returns a const iterator being/end of dictionary.
HdInstanceRegistry is a dictionary container of HdInstance.
ValueType const & GetValue() const
Returns the value.
HdInstanceRegistry(const HdInstanceRegistry &other)
Copy constructor.
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.
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.
void SetValue(ValueType const &value)
Update the value in dictionary indexed by the key.
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...
This class is used as an interface to a shared instance in HdInstanceRegistry.
KeyType const & GetKey() const
Returns the key.