mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-06 00:55:50 +00:00
Avoid key allocation to find tile in cache
This commit is contained in:
parent
9d61c49478
commit
68948bc847
@ -1,6 +1,8 @@
|
||||
#include "navmeshtilescache.hpp"
|
||||
#include "exceptions.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
namespace
|
||||
@ -61,8 +63,7 @@ namespace DetourNavigator
|
||||
if (tileValues == agentValues->second.end())
|
||||
return Value();
|
||||
|
||||
// TODO: use different function to make key to avoid unnecessary std::string allocation
|
||||
const auto tile = tileValues->second.mMap.find(makeNavMeshKey(recastMesh, offMeshConnections));
|
||||
const auto tile = tileValues->second.mMap.find(RecastMeshKeyView(recastMesh, offMeshConnections));
|
||||
if (tile == tileValues->second.mMap.end())
|
||||
return Value();
|
||||
|
||||
@ -163,4 +164,58 @@ namespace DetourNavigator
|
||||
mFreeItems.splice(mFreeItems.begin(), mBusyItems, iterator);
|
||||
mFreeNavMeshDataSize += getSize(*iterator);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CompareBytes
|
||||
{
|
||||
const char* mRhsIt;
|
||||
const char* mRhsEnd;
|
||||
|
||||
template <class T>
|
||||
int operator ()(const std::vector<T>& lhs)
|
||||
{
|
||||
const auto lhsBegin = reinterpret_cast<const char*>(lhs.data());
|
||||
const auto lhsEnd = reinterpret_cast<const char*>(lhs.data() + lhs.size());
|
||||
const auto lhsSize = static_cast<std::ptrdiff_t>(lhsEnd - lhsBegin);
|
||||
const auto rhsSize = static_cast<std::ptrdiff_t>(mRhsEnd - mRhsIt);
|
||||
const auto size = std::min(lhsSize, rhsSize);
|
||||
|
||||
if (const auto result = std::memcmp(lhsBegin, mRhsIt, size))
|
||||
return result;
|
||||
|
||||
if (lhsSize > rhsSize)
|
||||
return 1;
|
||||
|
||||
mRhsIt += size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int NavMeshTilesCache::RecastMeshKeyView::compare(const std::string& other) const
|
||||
{
|
||||
CompareBytes compareBytes {other.data(), other.data() + other.size()};
|
||||
|
||||
if (const auto result = compareBytes(mRecastMesh.get().getIndices()))
|
||||
return result;
|
||||
|
||||
if (const auto result = compareBytes(mRecastMesh.get().getVertices()))
|
||||
return result;
|
||||
|
||||
if (const auto result = compareBytes(mRecastMesh.get().getAreaTypes()))
|
||||
return result;
|
||||
|
||||
if (const auto result = compareBytes(mRecastMesh.get().getWater()))
|
||||
return result;
|
||||
|
||||
if (const auto result = compareBytes(mOffMeshConnections.get()))
|
||||
return result;
|
||||
|
||||
if (compareBytes.mRhsIt < compareBytes.mRhsEnd)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <cassert>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
@ -108,16 +109,54 @@ namespace DetourNavigator
|
||||
class KeyView
|
||||
{
|
||||
public:
|
||||
KeyView() = default;
|
||||
|
||||
KeyView(const std::string& value)
|
||||
: mValue(value) {}
|
||||
: mValue(&value) {}
|
||||
|
||||
const std::string& getValue() const
|
||||
{
|
||||
assert(mValue);
|
||||
return *mValue;
|
||||
}
|
||||
|
||||
virtual int compare(const std::string& other) const
|
||||
{
|
||||
assert(mValue);
|
||||
return mValue->compare(other);
|
||||
}
|
||||
|
||||
virtual bool isLess(const KeyView& other) const
|
||||
{
|
||||
assert(mValue);
|
||||
return other.compare(*mValue) > 0;
|
||||
}
|
||||
|
||||
friend bool operator <(const KeyView& lhs, const KeyView& rhs)
|
||||
{
|
||||
return lhs.mValue.get() < rhs.mValue.get();
|
||||
return lhs.isLess(rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
std::reference_wrapper<const std::string> mValue;
|
||||
const std::string* mValue = nullptr;
|
||||
};
|
||||
|
||||
class RecastMeshKeyView : public KeyView
|
||||
{
|
||||
public:
|
||||
RecastMeshKeyView(const RecastMesh& recastMesh, const std::vector<OffMeshConnection>& offMeshConnections)
|
||||
: mRecastMesh(recastMesh), mOffMeshConnections(offMeshConnections) {}
|
||||
|
||||
int compare(const std::string& other) const override;
|
||||
|
||||
bool isLess(const KeyView& other) const override
|
||||
{
|
||||
return compare(other.getValue()) < 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::reference_wrapper<const RecastMesh> mRecastMesh;
|
||||
std::reference_wrapper<const std::vector<OffMeshConnection>> mOffMeshConnections;
|
||||
};
|
||||
|
||||
struct TileMap
|
||||
|
Loading…
Reference in New Issue
Block a user