game engines/web frameworks: 27 CWE-407 defects + 3 CLEAN; 194 sites, 78 ecosystems
This commit is contained in:
parent
547a9f5738
commit
4d3fcc8e73
76 changed files with 6216 additions and 17 deletions
|
|
@ -0,0 +1,47 @@
|
|||
--- a/OgreMain/include/OgreNode.h
|
||||
+++ b/OgreMain/include/OgreNode.h
|
||||
@@ -28,6 +28,7 @@
|
||||
#ifndef _Node_H__
|
||||
#define _Node_H__
|
||||
|
||||
+#include <unordered_set>
|
||||
#include "OgrePrerequisites.h"
|
||||
|
||||
#include "OgreMatrix4.h"
|
||||
@@ -190,7 +191,7 @@ namespace Ogre {
|
||||
/** Queue of nodes pending update. */
|
||||
- typedef std::vector<Node*> QueuedUpdates;
|
||||
+ typedef std::unordered_set<Node*> QueuedUpdates;
|
||||
static QueuedUpdates msQueuedUpdates;
|
||||
|
||||
--- a/OgreMain/src/OgreNode.cpp
|
||||
+++ b/OgreMain/src/OgreNode.cpp
|
||||
@@ -71,12 +71,9 @@ namespace Ogre {
|
||||
if (mQueuedForUpdate)
|
||||
{
|
||||
- // Erase from queued updates
|
||||
- QueuedUpdates::iterator it =
|
||||
- std::find(msQueuedUpdates.begin(), msQueuedUpdates.end(), this);
|
||||
- assert(it != msQueuedUpdates.end());
|
||||
- if (it != msQueuedUpdates.end())
|
||||
- {
|
||||
- // Optimised algorithm to erase an element from unordered vector.
|
||||
- *it = msQueuedUpdates.back();
|
||||
- msQueuedUpdates.pop_back();
|
||||
- }
|
||||
+ // O(1) erase — unordered_set, no linear scan needed
|
||||
+ msQueuedUpdates.erase(this);
|
||||
+ mQueuedForUpdate = false;
|
||||
}
|
||||
|
||||
@@ -729,7 +720,7 @@ namespace Ogre {
|
||||
void Node::queueNeedUpdate(Node* n)
|
||||
{
|
||||
// Don't queue the node more than once
|
||||
if (!n->mQueuedForUpdate)
|
||||
{
|
||||
n->mQueuedForUpdate = true;
|
||||
- msQueuedUpdates.push_back(n);
|
||||
+ msQueuedUpdates.insert(n); // O(1) hash insert
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
--- a/OgreMain/src/OgreResourceGroupManager.cpp
|
||||
+++ b/OgreMain/src/OgreResourceGroupManager.cpp
|
||||
@@ -963,6 +963,7 @@ namespace Ogre {
|
||||
void ResourceGroupManager::_notifyAllResourcesRemoved(ResourceManager* manager) const
|
||||
{
|
||||
OGRE_LOCK_AUTO_MUTEX;
|
||||
+ #include <unordered_set> // ensure header present at TU level in real patch
|
||||
|
||||
// Iterate over all groups
|
||||
for (const auto & grpi : mResourceGroupMap)
|
||||
@@ -975,14 +976,22 @@ namespace Ogre {
|
||||
// Iterate over all resources and collect which should be removed
|
||||
std::vector<ResourcePtr> arDel;
|
||||
arDel.reserve(oi.second.size());
|
||||
for (const auto& iter : oi.second) {
|
||||
if (iter->getCreator() == manager)
|
||||
arDel.emplace_back(iter);
|
||||
}
|
||||
|
||||
- // Remove the items here (not above) to avoid iterator invalidation.
|
||||
- for (const auto& iter : arDel)
|
||||
- {
|
||||
- auto iFind = std::find(oi.second.begin(), oi.second.end(), iter); // O(N)
|
||||
- if (iFind != oi.second.end())
|
||||
- oi.second.erase(iFind);
|
||||
+ // Build O(1) membership set from raw pointers, then single-pass erase.
|
||||
+ // Two-phase approach preserved to avoid iterator invalidation during
|
||||
+ // resource destructor callbacks (see original comment).
|
||||
+ std::unordered_set<Resource*> toRemove;
|
||||
+ toRemove.reserve(arDel.size());
|
||||
+ for (const auto& r : arDel)
|
||||
+ toRemove.insert(r.get());
|
||||
+
|
||||
+ for (auto l = oi.second.begin(); l != oi.second.end(); )
|
||||
+ {
|
||||
+ if (toRemove.count(l->get()))
|
||||
+ l = oi.second.erase(l); // O(1) per erase on std::list
|
||||
+ else
|
||||
+ ++l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
--- a/OgreMain/include/OgreRibbonTrail.h
|
||||
+++ b/OgreMain/include/OgreRibbonTrail.h
|
||||
@@ -27,6 +27,7 @@ THE SOFTWARE.
|
||||
#pragma once
|
||||
|
||||
+#include <unordered_map>
|
||||
#include "OgreBillboardChain.h"
|
||||
#include "OgreNode.h"
|
||||
#include "OgreIteratorWrappers.h"
|
||||
@@ -93,6 +94,8 @@ namespace Ogre {
|
||||
NodeList mNodeList;
|
||||
typedef std::vector<size_t> IndexVector;
|
||||
IndexVector mNodeToChainSegment;
|
||||
+ /// Reverse map: chain segment index → node pointer (O(1) lookup in clearChain)
|
||||
+ std::unordered_map<size_t, Node*> mChainToNodeMap;
|
||||
IndexVector mFreeChains;
|
||||
typedef std::map<const Node*, size_t> NodeToChainSegmentMap;
|
||||
NodeToChainSegmentMap mNodeToSegMap;
|
||||
|
||||
--- a/OgreMain/src/OgreRibbonTrail.cpp
|
||||
+++ b/OgreMain/src/OgreRibbonTrail.cpp
|
||||
@@ -97,6 +97,7 @@ namespace Ogre {
|
||||
mNodeToChainSegment.push_back(chainIndex);
|
||||
mNodeToSegMap[n] = chainIndex;
|
||||
+ mChainToNodeMap[chainIndex] = n;
|
||||
|
||||
// initialise the chain
|
||||
resetTrail(chainIndex, n);
|
||||
@@ -130,6 +131,7 @@ namespace Ogre {
|
||||
size_t chainIndex = *mi;
|
||||
BillboardChain::clearChain(chainIndex);
|
||||
// mark as free now
|
||||
mFreeChains.push_back(chainIndex);
|
||||
+ mChainToNodeMap.erase(chainIndex);
|
||||
mNodeToSegMap.erase(n);
|
||||
mNodeList.erase(i);
|
||||
mNodeToChainSegment.erase(mi);
|
||||
@@ -199,12 +201,12 @@ namespace Ogre {
|
||||
void RibbonTrail::clearChain(size_t chainIndex)
|
||||
{
|
||||
BillboardChain::clearChain(chainIndex);
|
||||
|
||||
- // Reset if we are tracking for this chain
|
||||
- IndexVector::iterator i = std::find(mNodeToChainSegment.begin(),
|
||||
- mNodeToChainSegment.end(), chainIndex); // O(N)
|
||||
- if (i != mNodeToChainSegment.end())
|
||||
- {
|
||||
- size_t nodeIndex = std::distance(mNodeToChainSegment.begin(), i);
|
||||
- resetTrail(*i, mNodeList[nodeIndex]);
|
||||
+ // O(1) reverse lookup — replaced O(N) parallel-vector scan
|
||||
+ auto it = mChainToNodeMap.find(chainIndex);
|
||||
+ if (it != mChainToNodeMap.end())
|
||||
+ {
|
||||
+ resetTrail(chainIndex, it->second);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue