Use std::unordered_map in IndexedList for faster speed

Because mingw cross compiler g++-4.6.3 does not support
std::unordered_map::emplace and std::deque::emplace, traditional
insert member function is used instead.
pull/119/head
Tatsuhiro Tsujikawa 2013-08-21 23:46:16 +09:00
parent 252e91e0ac
commit ee2e21150b
1 changed files with 60 additions and 64 deletions

View File

@ -38,7 +38,7 @@
#include "common.h" #include "common.h"
#include <deque> #include <deque>
#include <map> #include <unordered_map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@ -333,9 +333,8 @@ public:
typedef KeyType key_type; typedef KeyType key_type;
typedef ValuePtrType value_type; typedef ValuePtrType value_type;
typedef std::map<KeyType, ValuePtrType> IndexType; typedef std::unordered_map<KeyType, ValuePtrType> IndexType;
typedef std::deque<std::pair<typename IndexType::iterator, typedef std::deque<std::pair<KeyType, ValuePtrType>> SeqType;
ValuePtrType> > SeqType;
@ -362,13 +361,13 @@ public:
// Inserts (|key|, |value|) to the end of the list. If the same key // Inserts (|key|, |value|) to the end of the list. If the same key
// has been already added, this function fails. This function // has been already added, this function fails. This function
// returns true if it succeeds. Complexity: O(logN) // returns true if it succeeds. Complexity: O(1)
bool push_back(KeyType key, ValuePtrType value) bool push_back(KeyType key, ValuePtrType value)
{ {
typename IndexType::iterator i = index_.lower_bound(key); auto i = index_.find(key);
if(i == index_.end() || (*i).first != key) { if(i == std::end(index_)) {
i = index_.insert(i, std::make_pair(key, value)); index_.insert({key, value});
seq_.push_back(std::make_pair(i, value)); seq_.emplace_back(key, value);
return true; return true;
} else { } else {
return false; return false;
@ -377,13 +376,13 @@ public:
// Inserts (|key|, |value|) to the front of the list. If the same // Inserts (|key|, |value|) to the front of the list. If the same
// key has been already added, this function fails. This function // key has been already added, this function fails. This function
// returns true if it succeeds. Complexity: O(logN) // returns true if it succeeds. Complexity: O(1)
bool push_front(KeyType key, ValuePtrType value) bool push_front(KeyType key, ValuePtrType value)
{ {
typename IndexType::iterator i = index_.lower_bound(key); auto i = index_.find(key);
if(i == index_.end() || (*i).first != key) { if(i == std::end(index_)) {
i = index_.insert(i, std::make_pair(key, value)); index_.insert({key, value});
seq_.push_front(std::make_pair(i, value)); seq_.emplace_front(key, value);
return true; return true;
} else { } else {
return false; return false;
@ -397,33 +396,32 @@ public:
iterator insert(size_t dest, KeyType key, ValuePtrType value) iterator insert(size_t dest, KeyType key, ValuePtrType value)
{ {
if(dest > size()) { if(dest > size()) {
return seq_.end(); return std::end(seq_);
} }
typename IndexType::iterator i = index_.lower_bound(key); auto i = index_.find(key);
if(i == index_.end() || (*i).first != key) { if(i == std::end(index_)) {
typename SeqType::iterator j = seq_.begin(); auto j = std::begin(seq_);
std::advance(j, dest); std::advance(j, dest);
i = index_.insert(i, std::make_pair(key, value)); index_.insert({key, value});
j = seq_.insert(j, std::make_pair(i, value)); return iterator(seq_.insert(j, {key, value}));
return iterator(j);
} else { } else {
return iterator(seq_.end()); return iterator(std::end(seq_));
} }
} }
// Inserts (|key|, |value|) to the position |dest|. If the same key // Inserts (|key|, |value|) to the position |dest|. If the same key
// has been already added, this function fails. This function // has been already added, this function fails. This function
// returns the iterator to the newly added element if it is // returns the iterator to the newly added element if it is
// succeeds, or end(). Complexity: O(logN) if inserted to the first // succeeds, or end(). Complexity: O(1) if inserted to the first or
// or last, otherwise O(N) // last, otherwise O(N)
iterator insert(iterator dest, KeyType key, ValuePtrType value) iterator insert(iterator dest, KeyType key, ValuePtrType value)
{ {
typename IndexType::iterator i = index_.lower_bound(key); auto i = index_.find(key);
if(i == index_.end() || (*i).first != key) { if(i == std::end(index_)) {
i = index_.insert(i, std::make_pair(key, value)); index_.insert({key, value});
return iterator(seq_.insert(dest.p, std::make_pair(i, value))); return iterator(seq_.insert(dest.p, {key, value}));
} else { } else {
return iterator(seq_.end()); return iterator(std::end(seq_));
} }
} }
@ -437,14 +435,14 @@ public:
std::vector<typename SeqType::value_type> v; std::vector<typename SeqType::value_type> v;
v.reserve(std::distance(first, last)); v.reserve(std::distance(first, last));
for(; first != last; ++first) { for(; first != last; ++first) {
KeyType key = keyFunc(*first); auto key = keyFunc(*first);
typename IndexType::iterator i = index_.lower_bound(key); auto i = index_.find(key);
if(i == index_.end() || (*i).first != key) { if(i == std::end(index_)) {
i = index_.insert(i, std::make_pair(key, *first)); index_.insert({key, *first});
v.push_back(std::make_pair(i, *first)); v.emplace_back(key, *first);
} }
} }
seq_.insert(dest.p, v.begin(), v.end()); seq_.insert(dest.p, std::begin(v), std::end(v));
} }
template<typename KeyFunc, typename InputIterator> template<typename KeyFunc, typename InputIterator>
@ -457,14 +455,14 @@ public:
std::vector<typename SeqType::value_type> v; std::vector<typename SeqType::value_type> v;
v.reserve(std::distance(first, last)); v.reserve(std::distance(first, last));
for(; first != last; ++first) { for(; first != last; ++first) {
KeyType key = keyFunc(*first); auto key = keyFunc(*first);
typename IndexType::iterator i = index_.lower_bound(key); auto i = index_.find(key);
if(i == index_.end() || (*i).first != key) { if(i == std::end(index_)) {
i = index_.insert(i, std::make_pair(key, *first)); index_.insert({key, *first});
v.push_back(std::make_pair(i, *first)); v.emplace_back(key, *first);
} }
} }
seq_.insert(seq_.begin() + pos, v.begin(), v.end()); seq_.insert(std::begin(seq_) + pos, std::begin(v), std::end(v));
} }
// Removes |key| from the list. If the element is not found, this // Removes |key| from the list. If the element is not found, this
@ -472,13 +470,12 @@ public:
// succeeds. Complexity: O(N) // succeeds. Complexity: O(N)
bool remove(KeyType key) bool remove(KeyType key)
{ {
typename IndexType::iterator i = index_.find(key); auto i = index_.find(key);
if(i == index_.end()) { if(i == std::end(index_)) {
return false; return false;
} }
for(typename SeqType::iterator j = seq_.begin(), eoj = seq_.end(); for(auto j = std::begin(seq_), eoj = std::end(seq_); j != eoj; ++j) {
j != eoj; ++j) { if((*j).first == key) {
if((*j).first == i) {
seq_.erase(j); seq_.erase(j);
break; break;
} }
@ -502,13 +499,13 @@ public:
template<typename Pred> template<typename Pred>
void remove_if(Pred pred) void remove_if(Pred pred)
{ {
typename SeqType::iterator first = seq_.begin(), last = seq_.end(); auto first = std::begin(seq_), last = std::end(seq_);
for(; first != last && !pred((*first).second); ++first); for(; first != last && !pred((*first).second); ++first);
if(first == last) { if(first == last) {
return; return;
} }
index_.erase((*first).first); index_.erase((*first).first);
typename SeqType::iterator store = first; auto store = first;
++first; ++first;
for(; first != last; ++first) { for(; first != last; ++first) {
if(pred((*first).second)) { if(pred((*first).second)) {
@ -522,14 +519,13 @@ public:
// Removes element at the front of the list. If the list is empty, // Removes element at the front of the list. If the list is empty,
// this function fails. This function returns true if it // this function fails. This function returns true if it
// succeeds. Complexity: O(logN) // succeeds. Complexity: O(1)
bool pop_front() bool pop_front()
{ {
if(seq_.empty()) { if(seq_.empty()) {
return false; return false;
} }
typename IndexType::iterator i = seq_.front().first; index_.erase(seq_.front().first);
index_.erase(i);
seq_.pop_front(); seq_.pop_front();
return true; return true;
} }
@ -545,17 +541,17 @@ public:
// O(N) // O(N)
ssize_t move(KeyType key, ssize_t offset, OffsetMode how) ssize_t move(KeyType key, ssize_t offset, OffsetMode how)
{ {
typename IndexType::iterator idxent = index_.find(key); auto idxent = index_.find(key);
if(idxent == index_.end()) { if(idxent == std::end(index_)) {
return -1; return -1;
} }
typename SeqType::iterator x = seq_.begin(), eseq = seq_.end(); auto x = std::begin(seq_), eseq = std::end(seq_);
for(; x != eseq; ++x) { for(; x != eseq; ++x) {
if((*x).first == idxent) { if((*x).first == (*idxent).first) {
break; break;
} }
} }
ssize_t xp = std::distance(seq_.begin(), x); ssize_t xp = std::distance(std::begin(seq_), x);
ssize_t size = index_.size(); ssize_t size = index_.size();
ssize_t dest; ssize_t dest;
if(how == OFFSET_MODE_CUR) { if(how == OFFSET_MODE_CUR) {
@ -574,7 +570,7 @@ public:
} }
dest = std::max(dest, static_cast<ssize_t>(0)); dest = std::max(dest, static_cast<ssize_t>(0));
} }
typename SeqType::iterator d = seq_.begin(); auto d = std::begin(seq_);
std::advance(d, dest); std::advance(d, dest);
if(xp < dest) { if(xp < dest) {
std::rotate(x, x+1, d+1); std::rotate(x, x+1, d+1);
@ -585,11 +581,11 @@ public:
} }
// Returns the value associated by |key|. If it is not found, // Returns the value associated by |key|. If it is not found,
// returns ValuePtrType(). Complexity: O(logN) // returns ValuePtrType(). Complexity: O(1)
ValuePtrType get(KeyType key) const ValuePtrType get(KeyType key) const
{ {
typename IndexType::const_iterator idxent = index_.find(key); auto idxent = index_.find(key);
if(idxent == index_.end()) { if(idxent == std::end(index_)) {
return ValuePtrType(); return ValuePtrType();
} else { } else {
return (*idxent).second; return (*idxent).second;
@ -608,22 +604,22 @@ public:
iterator begin() iterator begin()
{ {
return iterator(seq_.begin()); return iterator(std::begin(seq_));
} }
iterator end() iterator end()
{ {
return iterator(seq_.end()); return iterator(std::end(seq_));
} }
const_iterator begin() const const_iterator begin() const
{ {
return const_iterator(seq_.begin()); return const_iterator(std::begin(seq_));
} }
const_iterator end() const const_iterator end() const
{ {
return const_iterator(seq_.end()); return const_iterator(std::end(seq_));
} }
// Removes all elements from the list. // Removes all elements from the list.