apply patch #2819: Change unit_map to a faster implementation by thonsew
This commit is contained in:
parent
31d619503c
commit
9da3b6ac61
4 changed files with 43 additions and 37 deletions
|
@ -14,8 +14,8 @@ The release team should empty this file after each release.
|
|||
CHANGES
|
||||
=======
|
||||
|
||||
[section="title"]
|
||||
text
|
||||
[section="Dependencies"]
|
||||
Wesnoth now requires boost 1.36 to have unordered map
|
||||
[/section]
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ class variable_set;
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#define MAX_MAP_AREA 65536
|
||||
|
||||
|
@ -98,6 +99,8 @@ struct map_location {
|
|||
static DIRECTION get_opposite_dir(DIRECTION d);
|
||||
|
||||
static const map_location null_location;
|
||||
|
||||
friend std::size_t hash_value(map_location const &a);
|
||||
};
|
||||
|
||||
/** Function which tells if two locations are adjacent. */
|
||||
|
@ -138,4 +141,10 @@ std::ostream &operator<<(std::ostream &s, map_location const &l);
|
|||
/** Dumps a vector of positions on a stream, for debug purposes. */
|
||||
std::ostream &operator<<(std::ostream &s, std::vector<map_location> const &v);
|
||||
|
||||
/** Inlined bodies **/
|
||||
inline std::size_t hash_value(map_location const & a){
|
||||
boost::hash<size_t> h;
|
||||
return h( (a.x << 16) ^ a.y );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "log.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include "unit_map.hpp"
|
||||
|
||||
static lg::log_domain log_engine("engine");
|
||||
#define ERR_NG LOG_STREAM(err, log_engine)
|
||||
|
@ -54,30 +55,10 @@ void unit_map::swap(unit_map &o)
|
|||
std::swap(num_invalid_, o.num_invalid_);
|
||||
}
|
||||
|
||||
unit_map::~unit_map()
|
||||
{
|
||||
unit_map::~unit_map() {
|
||||
clear();
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::find(const map_location &loc) {
|
||||
lmap::const_iterator i = lmap_.find(loc);
|
||||
if (i == lmap_.end()) {
|
||||
return unit_iterator(map_.end(), this);
|
||||
}
|
||||
|
||||
umap::iterator iter = map_.find(i->second);
|
||||
|
||||
assert(is_valid(iter));
|
||||
return unit_iterator(iter, this);
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::find(size_t id)
|
||||
{
|
||||
umap::iterator iter = map_.find(id);
|
||||
if (!is_valid(iter)) iter = map_.end();
|
||||
return unit_iterator(iter, this);
|
||||
}
|
||||
|
||||
unit_map::unit_iterator unit_map::begin() {
|
||||
// This call just needs to go somewhere that is likely to be
|
||||
// called when num_iters_ == 0. This seems as good a place as any.
|
||||
|
@ -151,8 +132,9 @@ void unit_map::insert(unit *p)
|
|||
DBG_NG << "Adding unit " << p->underlying_id() << " - " << p->id()
|
||||
<< " to location: (" << loc << ")\n";
|
||||
|
||||
std::pair<lmap::iterator,bool> res = lmap_.insert(std::make_pair(loc, unit_id));
|
||||
std::pair<lmap::iterator,bool> res = lmap_.insert(std::make_pair(loc, biter.first));
|
||||
assert(res.second);
|
||||
|
||||
}
|
||||
|
||||
void unit_map::replace(const map_location &l, const unit &u)
|
||||
|
@ -184,17 +166,17 @@ void unit_map::clear()
|
|||
unit *unit_map::extract(const map_location &loc)
|
||||
{
|
||||
lmap::iterator i = lmap_.find(loc);
|
||||
if (i == lmap_.end())
|
||||
return NULL;
|
||||
if (i == lmap_.end()) {
|
||||
return NULL; }
|
||||
|
||||
umap::iterator iter = map_.find(i->second);
|
||||
umap::iterator iter = i->second;
|
||||
unit *res = iter->second;
|
||||
|
||||
DBG_NG << "Extract unit " << res->underlying_id() << " - " << res->id()
|
||||
<< " from location: (" << loc << ")\n";
|
||||
iter->second = NULL;
|
||||
++num_invalid_;
|
||||
lmap_.erase(i);
|
||||
lmap_.erase_return_void(i);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
class unit;
|
||||
|
||||
|
@ -41,11 +42,10 @@ class unit;
|
|||
* @note Iterators prevent ghost units from being collected. So they should
|
||||
* never be stored into data structures, as it will cause slowdowns!
|
||||
*/
|
||||
class unit_map
|
||||
{
|
||||
class unit_map {
|
||||
public:
|
||||
typedef std::map<size_t, unit *> umap;
|
||||
typedef std::map<map_location, size_t> lmap;
|
||||
typedef boost::unordered_map<size_t, unit *> umap;
|
||||
typedef boost::unordered_map<map_location, umap::iterator> lmap;
|
||||
|
||||
unit_map() : map_(), lmap_(), num_iters_(0), num_invalid_(0) { };
|
||||
unit_map(const unit_map &that);
|
||||
|
@ -129,8 +129,9 @@ public:
|
|||
iterator_base& operator--()
|
||||
{
|
||||
assert(map_ && i_ != map_->map_.begin());
|
||||
do --i_;
|
||||
while (i_ != map_->map_.begin() && !i_->second);
|
||||
iterator_type next(map_->map_.begin()), oldi(i_);
|
||||
do { i_ = ++next;
|
||||
}while(next != oldi );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -183,8 +184,20 @@ public:
|
|||
typedef unit_iterator iterator;
|
||||
typedef const_unit_iterator const_iterator;
|
||||
|
||||
unit_iterator find(const map_location& loc) ;
|
||||
unit_iterator find(size_t id);
|
||||
unit_iterator find(size_t id) {
|
||||
umap::iterator iter = map_.find(id);
|
||||
if (!is_valid(iter)) iter = map_.end();
|
||||
return unit_iterator(iter, this);
|
||||
}
|
||||
|
||||
unit_iterator find(const map_location &loc) {
|
||||
lmap::const_iterator i = lmap_.find(loc);
|
||||
if (i == lmap_.end()) {
|
||||
return unit_iterator(map_.end(), this);
|
||||
}
|
||||
assert(is_valid(i->second));
|
||||
return unit_iterator(i->second, this);
|
||||
}
|
||||
|
||||
const_unit_iterator find(const map_location &loc) const
|
||||
{ return const_cast<unit_map *>(this)->find(loc); }
|
||||
|
@ -199,7 +212,7 @@ public:
|
|||
std::vector<unit_iterator> find_leaders(int side);
|
||||
std::vector<const_unit_iterator> find_leaders(int side) const;
|
||||
|
||||
size_t count(const map_location& loc) const { return lmap_.count(loc); }
|
||||
size_t count(const map_location& loc) const { return static_cast<size_t>(lmap_.count(loc)); }
|
||||
|
||||
unit_iterator begin();
|
||||
const_unit_iterator begin() const;
|
||||
|
@ -291,4 +304,6 @@ void unit_map::erase(const T& iter) {
|
|||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // UNIT_MAP_H_INCLUDED
|
||||
|
|
Loading…
Add table
Reference in a new issue