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 template <
typename Callback>
190 size_t size()
const {
return _dictionary.size(); }
195 template <
typename T>
196 static bool _IsUnique(std::shared_ptr<T>
const &value) {
197 return value.unique();
200 typename InstanceType::Dictionary _dictionary;
201 typename InstanceType::RegistryMutex _registryMutex;
209 template <
typename VALUE>
212 typename HdInstance<VALUE>::KeyType
const &key)
215 HF_MALLOC_TAG_FUNCTION();
219 typename InstanceType::RegistryLock lock(_registryMutex);
221 typename InstanceType::Dictionary::iterator it = _dictionary.find(key);
222 if (it == _dictionary.end()) {
224 it = _dictionary.insert(
225 std::make_pair(key,
typename InstanceType::ValueHolder())).first;
228 it->second.ResetRecycleCounter();
229 return InstanceType(key, it->second.value, std::move(lock), &_dictionary);
232 template <
typename VALUE>
235 typename HdInstance<VALUE>::KeyType
const &key,
bool *found)
238 HF_MALLOC_TAG_FUNCTION();
242 typename InstanceType::RegistryLock lock(_registryMutex);
244 typename InstanceType::Dictionary::iterator it = _dictionary.find(key);
245 if (it == _dictionary.end()) {
247 return InstanceType(key, VALUE(), std::move(lock),
nullptr);
250 it->second.ResetRecycleCounter();
251 return InstanceType(key, it->second.value,std::move(lock),&_dictionary);
255 template <
typename VALUE>
260 return GarbageCollect([](
void*){}, recycleCount);
263 template <
typename VALUE>
264 template <
typename Callback>
269 HF_MALLOC_TAG_FUNCTION();
272 if (recycleCount < 0) {
273 return _dictionary.size();
276 size_t inUseCount = 0;
277 for (
typename InstanceType::Dictionary::iterator it = _dictionary.begin();
278 it != _dictionary.end();) {
281 bool isUnique = _IsUnique(it->second.value);
282 if (isUnique && (++it->second.recycleCounter > recycleCount)) {
283 std::forward<Callback>(callback)(it->second.value.get());
284 it = _dictionary.unsafe_erase(it);
293 template <
typename VALUE>
298 HF_MALLOC_TAG_FUNCTION();
304 PXR_NAMESPACE_CLOSE_SCOPE
306 #endif // PXR_IMAGING_HD_INSTANCE_REGISTRY_H HdInstance(KeyType const &key)
Construct an instance with no lock or registry container.
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.
bool IsFirstInstance() const
Returns true if the value has not been initialized.
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.