mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-02 23:15:33 +00:00
Replace land static container from vector to flat_set
I use a ordered container to fix the "is there any other way to speed this up?". The flat_set allow to have the same locality when searching an element. I use the is_transparent C++14 feature to avoid to create a dummy Land when searching I use a unique_ptr to avoid to manualy manage the memory
This commit is contained in:
parent
d843ec321e
commit
f81be5b463
2 changed files with 34 additions and 48 deletions
|
@ -11,25 +11,6 @@
|
|||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Compare
|
||||
{
|
||||
bool operator()(const ESM::Land *x, const ESM::Land *y) {
|
||||
if (x->mX == y->mX) {
|
||||
return x->mY < y->mY;
|
||||
}
|
||||
return x->mX < y->mX;
|
||||
}
|
||||
bool operator()(const ESM::Land *x, const std::pair<int, int>& y) {
|
||||
if (x->mX == y.first) {
|
||||
return x->mY < y.second;
|
||||
}
|
||||
return x->mX < y.first;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
RecordId::RecordId(const std::string &id, bool isDeleted)
|
||||
|
@ -425,11 +406,6 @@ namespace MWWorld
|
|||
//=========================================================================
|
||||
Store<ESM::Land>::~Store()
|
||||
{
|
||||
for (const ESM::Land* staticLand : mStatic)
|
||||
{
|
||||
delete staticLand;
|
||||
}
|
||||
|
||||
}
|
||||
size_t Store<ESM::Land>::getSize() const
|
||||
{
|
||||
|
@ -446,12 +422,8 @@ namespace MWWorld
|
|||
const ESM::Land *Store<ESM::Land>::search(int x, int y) const
|
||||
{
|
||||
std::pair<int, int> comp(x,y);
|
||||
|
||||
std::vector<ESM::Land *>::const_iterator it =
|
||||
std::lower_bound(mStatic.begin(), mStatic.end(), comp, Compare());
|
||||
|
||||
if (it != mStatic.end() && (*it)->mX == x && (*it)->mY == y) {
|
||||
return *it;
|
||||
if (auto it = mStatic.find(comp); it != mStatic.end() && (*it)->mX == x && (*it)->mY == y) {
|
||||
return it->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -467,24 +439,13 @@ namespace MWWorld
|
|||
}
|
||||
RecordId Store<ESM::Land>::load(ESM::ESMReader &esm)
|
||||
{
|
||||
ESM::Land *ptr = new ESM::Land();
|
||||
auto ptr = std::make_unique<ESM::Land>();
|
||||
bool isDeleted = false;
|
||||
|
||||
ptr->load(esm, isDeleted);
|
||||
|
||||
// Same area defined in multiple plugins? -> last plugin wins
|
||||
// Can't use search() because we aren't sorted yet - is there any other way to speed this up?
|
||||
for (std::vector<ESM::Land*>::iterator it = mStatic.begin(); it != mStatic.end(); ++it)
|
||||
{
|
||||
if ((*it)->mX == ptr->mX && (*it)->mY == ptr->mY)
|
||||
{
|
||||
delete *it;
|
||||
mStatic.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mStatic.push_back(ptr);
|
||||
mStatic.insert(std::move(ptr));
|
||||
|
||||
return RecordId("", isDeleted);
|
||||
}
|
||||
|
@ -494,7 +455,6 @@ namespace MWWorld
|
|||
if (mBuilt)
|
||||
return;
|
||||
|
||||
std::sort(mStatic.begin(), mStatic.end(), Compare());
|
||||
mBuilt = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
|
||||
#include "recordcmp.hpp"
|
||||
|
||||
|
@ -74,10 +76,10 @@ namespace MWWorld
|
|||
const T *find(int index) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
template <class T, class Container=std::vector<T*>>
|
||||
class SharedIterator
|
||||
{
|
||||
typedef typename std::vector<T *>::const_iterator Iter;
|
||||
typedef typename Container::const_iterator Iter;
|
||||
|
||||
Iter mIter;
|
||||
|
||||
|
@ -233,10 +235,34 @@ namespace MWWorld
|
|||
template <>
|
||||
class Store<ESM::Land> : public StoreBase
|
||||
{
|
||||
std::vector<ESM::Land *> mStatic;
|
||||
struct SpatialComparator
|
||||
{
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator()(const std::unique_ptr<ESM::Land>& x, const std::unique_ptr<ESM::Land>& y) const {
|
||||
if (x->mX == y->mX) {
|
||||
return x->mY < y->mY;
|
||||
}
|
||||
return x->mX < y->mX;
|
||||
}
|
||||
bool operator()(const std::unique_ptr<ESM::Land>& x, const std::pair<int, int>& y) const {
|
||||
if (x->mX == y.first) {
|
||||
return x->mY < y.second;
|
||||
}
|
||||
return x->mX < y.first;
|
||||
}
|
||||
bool operator()(const std::pair<int, int>& x, const std::unique_ptr<ESM::Land>& y) const {
|
||||
if (x.first == y->mX) {
|
||||
return x.second < y->mY;
|
||||
}
|
||||
return x.first < y->mX;
|
||||
}
|
||||
};
|
||||
using Statics = boost::container::flat_set<std::unique_ptr<ESM::Land>, SpatialComparator>;
|
||||
Statics mStatic;
|
||||
|
||||
public:
|
||||
typedef SharedIterator<ESM::Land> iterator;
|
||||
typedef SharedIterator<ESM::Land, Statics> iterator;
|
||||
|
||||
virtual ~Store();
|
||||
|
||||
|
|
Loading…
Reference in a new issue