git.s-ol.nu ~forks/DiligentCore / 212c9d5
Updated ResourceMappingImpl assiduous 10 months ago
3 changed file(s) with 49 addition(s) and 68 deletion(s). Raw diff Collapse all Expand all
207207 }
208208 };
209209
210 private:
210 protected:
211211 static constexpr size_t StrOwnershipBit = sizeof(size_t) * 8 - 1;
212212 static constexpr size_t StrOwnershipMask = size_t{1} << StrOwnershipBit;
213213 static constexpr size_t HashMask = ~StrOwnershipMask;
3939
4040 namespace Diligent
4141 {
42 struct ResMappingHashKey
43 {
44 ResMappingHashKey(const Char* Str, bool bMakeCopy, Uint32 ArrInd) :
45 StrKey{Str, bMakeCopy},
46 ArrayIndex{ArrInd}
47 {
48 }
4942
50 ResMappingHashKey(ResMappingHashKey&& rhs) :
51 StrKey{std::move(rhs.StrKey)},
52 ArrayIndex{rhs.ArrayIndex}
53 {}
54
55 bool operator==(const ResMappingHashKey& RHS) const
56 {
57 return StrKey == RHS.StrKey && ArrayIndex == RHS.ArrayIndex;
58 }
59
60 size_t GetHash() const
61 {
62 if (Hash == 0)
63 {
64 Hash = ComputeHash(StrKey.GetHash(), ArrayIndex);
65 }
66
67 return Hash;
68 }
69
70 // clang-format off
71 ResMappingHashKey ( const ResMappingHashKey& ) = delete;
72 ResMappingHashKey& operator = ( const ResMappingHashKey& ) = delete;
73 ResMappingHashKey& operator = ( ResMappingHashKey&& ) = delete;
74 // clang-format on
75
76 HashMapStringKey StrKey;
77 Uint32 ArrayIndex;
78 mutable size_t Hash = 0;
79 };
80 } // namespace Diligent
81
82 namespace std
83 {
84 template <>
85 struct hash<Diligent::ResMappingHashKey>
86 {
87 size_t operator()(const Diligent::ResMappingHashKey& Key) const
88 {
89 return Key.GetHash();
90 }
91 };
92 } // namespace std
93
94 namespace Diligent
95 {
9643 class FixedBlockMemoryAllocator;
9744
9845 /// Implementation of the resource mapping
10451 /// \param pRefCounters - reference counters object that controls the lifetime of this resource mapping
10552 /// \param RawMemAllocator - raw memory allocator that is used by the m_HashTable member
10653 ResourceMappingImpl(IReferenceCounters* pRefCounters, IMemoryAllocator& RawMemAllocator) :
107 TObjectBase(pRefCounters),
108 m_HashTable(STD_ALLOCATOR_RAW_MEM(HashTableElem, RawMemAllocator, "Allocator for unordered_map< ResMappingHashKey, RefCntAutoPtr<IDeviceObject> >"))
54 TObjectBase{pRefCounters},
55 m_HashTable{STD_ALLOCATOR_RAW_MEM(HashTableElem, RawMemAllocator, "Allocator for unordered_map<ResMappingHashKey, RefCntAutoPtr<IDeviceObject>>")}
10956 {}
11057
11158 ~ResourceMappingImpl();
11259
113 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
60 IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ResourceMapping, TObjectBase)
11461
11562 /// Implementation of IResourceMapping::AddResource()
11663 virtual void DILIGENT_CALL_TYPE AddResource(const Char* Name,
13683 virtual size_t DILIGENT_CALL_TYPE GetSize() override final;
13784
13885 private:
86 struct ResMappingHashKey : public HashMapStringKey
87 {
88 using TBase = HashMapStringKey;
89
90 ResMappingHashKey(const Char* Str, bool bMakeCopy, Uint32 ArrInd) :
91 HashMapStringKey{Str, bMakeCopy},
92 ArrayIndex{ArrInd}
93 {
94 Ownership_Hash = (ComputeHash(GetHash(), ArrInd) & HashMask) | (Ownership_Hash & StrOwnershipMask);
95 }
96
97 ResMappingHashKey(ResMappingHashKey&& rhs) :
98 HashMapStringKey{std::move(rhs)},
99 ArrayIndex{rhs.ArrayIndex}
100 {}
101
102 // clang-format off
103 ResMappingHashKey ( const ResMappingHashKey& ) = delete;
104 ResMappingHashKey& operator = ( const ResMappingHashKey& ) = delete;
105 ResMappingHashKey& operator = ( ResMappingHashKey&& ) = delete;
106 // clang-format on
107
108 bool operator==(const ResMappingHashKey& RHS) const
109 {
110 return static_cast<const TBase&>(*this) == static_cast<const TBase&>(RHS) && ArrayIndex == RHS.ArrayIndex;
111 }
112
113 const Uint32 ArrayIndex;
114 };
115
139116 ThreadingTools::LockHelper Lock();
140117
141 ThreadingTools::LockFlag m_LockFlag;
142 typedef std::pair<const ResMappingHashKey, RefCntAutoPtr<IDeviceObject>> HashTableElem;
143 std::unordered_map<ResMappingHashKey, RefCntAutoPtr<IDeviceObject>, std::hash<ResMappingHashKey>, std::equal_to<ResMappingHashKey>, STDAllocatorRawMem<HashTableElem>> m_HashTable;
118 ThreadingTools::LockFlag m_LockFlag;
119
120 using HashTableElem = std::pair<const ResMappingHashKey, RefCntAutoPtr<IDeviceObject>>;
121 std::unordered_map<ResMappingHashKey,
122 RefCntAutoPtr<IDeviceObject>,
123 ResMappingHashKey::Hasher,
124 std::equal_to<ResMappingHashKey>,
125 STDAllocatorRawMem<HashTableElem>>
126 m_HashTable;
144127 };
128
145129 } // namespace Diligent
2929
3030 namespace Diligent
3131 {
32
3233 ResourceMappingImpl::~ResourceMappingImpl()
3334 {
3435 }
35
36 IMPLEMENT_QUERY_INTERFACE(ResourceMappingImpl, IID_ResourceMapping, TObjectBase)
3736
3837 ThreadingTools::LockHelper ResourceMappingImpl::Lock()
3938 {
5150 auto* pObject = ppObjects[Elem];
5251
5352 // Try to construct new element in place
54 auto Elems =
55 m_HashTable.emplace(
56 std::make_pair(Diligent::ResMappingHashKey(Name, true, StartIndex + Elem), // Make a copy of the source string
57 Diligent::RefCntAutoPtr<IDeviceObject>(pObject)));
53 auto Elems = m_HashTable.emplace(ResMappingHashKey{Name, true /*Make copy*/, StartIndex + Elem}, pObject);
5854 // If there is already element with the same name, replace it
5955 if (!Elems.second && Elems.first->second != pObject)
6056 {
8480 auto LockHelper = Lock();
8581 // Remove object with the given name
8682 // Name will be implicitly converted to HashMapStringKey without making a copy
87 m_HashTable.erase(ResMappingHashKey(Name, false, ArrayIndex));
83 m_HashTable.erase(ResMappingHashKey{Name, false, ArrayIndex});
8884 }
8985
9086 void ResourceMappingImpl::GetResource(const Char* Name, IDeviceObject** ppResource, Uint32 ArrayIndex)
104100
105101 // Find an object with the requested name
106102 // Name will be implicitly converted to HashMapStringKey without making a copy
107 auto It = m_HashTable.find(ResMappingHashKey(Name, false, ArrayIndex));
103 auto It = m_HashTable.find(ResMappingHashKey{Name, false, ArrayIndex});
108104 if (It != m_HashTable.end())
109105 {
110106 *ppResource = It->second.RawPtr();
117113 {
118114 return m_HashTable.size();
119115 }
116
120117 } // namespace Diligent