Fixed inline problem for hollow iterator.
This commit is contained in:
parent
ea1cb4709e
commit
c52152bcb4
@ -30,11 +30,13 @@ struct hollow_iterator_base
|
|||||||
typedef self_type& self_reference;
|
typedef self_type& self_reference;
|
||||||
typedef typename iterator::reference reference;
|
typedef typename iterator::reference reference;
|
||||||
typedef typename iterator::pointer pointer;
|
typedef typename iterator::pointer pointer;
|
||||||
hollow_iterator_base() : it_(), empty_() { }
|
inline hollow_iterator_base() : it_(), empty_() { }
|
||||||
hollow_iterator_base(iterator it, is_empty empty) : it_(it), empty_(empty) {
|
inline hollow_iterator_base(iterator it, is_empty empty, bool solid) : it_(it), empty_(empty) {
|
||||||
advance();
|
if (!solid) advance();
|
||||||
}
|
}
|
||||||
hollow_iterator_base(const self_type& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; }
|
// Same as above, assumes solid==true.
|
||||||
|
inline hollow_iterator_base(iterator it, is_empty empty) : it_(it), empty_(empty) {}
|
||||||
|
inline hollow_iterator_base(const self_type& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; }
|
||||||
template <typename const_iterator>
|
template <typename const_iterator>
|
||||||
hollow_iterator_base(const hollow_iterator_base<const_iterator, is_empty>& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; }
|
hollow_iterator_base(const hollow_iterator_base<const_iterator, is_empty>& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; }
|
||||||
|
|
||||||
@ -58,13 +60,22 @@ struct hollow_iterator_base
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename container_type, typename iterator> auto make_hollow(
|
template <typename container_type, typename iterator>
|
||||||
|
inline auto make_solid(
|
||||||
container_type* v, const vector<bool>* p, iterator it) ->
|
container_type* v, const vector<bool>* p, iterator it) ->
|
||||||
hollow_iterator_base<iterator, is_empty<const container_type>> {
|
hollow_iterator_base<iterator, is_empty<const container_type>> {
|
||||||
return hollow_iterator_base<iterator, is_empty<const container_type>>(
|
return hollow_iterator_base<iterator, is_empty<const container_type>>(
|
||||||
it, is_empty<const container_type>(v, p));
|
it, is_empty<const container_type>(v, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename container_type, typename iterator>
|
||||||
|
inline auto make_hollow(
|
||||||
|
container_type* v, const vector<bool>* p, iterator it) ->
|
||||||
|
hollow_iterator_base<iterator, is_empty<const container_type>> {
|
||||||
|
return hollow_iterator_base<iterator, is_empty<const container_type>>(
|
||||||
|
it, is_empty<const container_type>(v, p), false);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace cxxmph
|
} // namespace cxxmph
|
||||||
|
|
||||||
#endif // __CXXMPH_HOLLOW_ITERATOR_H__
|
#endif // __CXXMPH_HOLLOW_ITERATOR_H__
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "mph_bits.h"
|
#include "mph_bits.h"
|
||||||
#include "mph_index.h"
|
#include "mph_index.h"
|
||||||
|
#include "hollow_iterator.h"
|
||||||
|
|
||||||
namespace cxxmph {
|
namespace cxxmph {
|
||||||
|
|
||||||
@ -46,14 +47,15 @@ class mph_map {
|
|||||||
typedef HashFcn hasher;
|
typedef HashFcn hasher;
|
||||||
typedef EqualKey key_equal;
|
typedef EqualKey key_equal;
|
||||||
|
|
||||||
typedef typename std::vector<value_type>::pointer pointer;
|
typedef typename vector<value_type>::pointer pointer;
|
||||||
typedef typename std::vector<value_type>::reference reference;
|
typedef typename vector<value_type>::reference reference;
|
||||||
typedef typename std::vector<value_type>::const_reference const_reference;
|
typedef typename vector<value_type>::const_reference const_reference;
|
||||||
typedef typename std::vector<value_type>::size_type size_type;
|
typedef typename vector<value_type>::size_type size_type;
|
||||||
typedef typename std::vector<value_type>::difference_type difference_type;
|
typedef typename vector<value_type>::difference_type difference_type;
|
||||||
|
|
||||||
typedef typename std::vector<value_type>::iterator iterator;
|
typedef is_empty<const vector<value_type>> is_empty_type;
|
||||||
typedef typename std::vector<value_type>::const_iterator const_iterator;
|
typedef hollow_iterator_base<typename vector<value_type>::iterator, is_empty_type> iterator;
|
||||||
|
typedef hollow_iterator_base<typename vector<value_type>::const_iterator, is_empty_type> const_iterator;
|
||||||
|
|
||||||
// For making macros simpler.
|
// For making macros simpler.
|
||||||
typedef void void_type;
|
typedef void void_type;
|
||||||
@ -80,7 +82,7 @@ class mph_map {
|
|||||||
data_type& operator[](const key_type &k);
|
data_type& operator[](const key_type &k);
|
||||||
const data_type& operator[](const key_type &k) const;
|
const data_type& operator[](const key_type &k) const;
|
||||||
|
|
||||||
size_type bucket_count() const { return index_.minimal_perfect_hash_size() + slack_.bucket_count(); }
|
size_type bucket_count() const { return index_.perfect_hash_size() + slack_.bucket_count(); }
|
||||||
void rehash(size_type nbuckets /*ignored*/);
|
void rehash(size_type nbuckets /*ignored*/);
|
||||||
|
|
||||||
protected: // mimicking STL implementation
|
protected: // mimicking STL implementation
|
||||||
@ -101,8 +103,8 @@ class mph_map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pack();
|
void pack();
|
||||||
std::vector<value_type> values_;
|
vector<value_type> values_;
|
||||||
std::vector<bool> present_;
|
vector<bool> present_;
|
||||||
SimpleMPHIndex<Key, typename seeded_hash<HashFcn>::hash_function> index_;
|
SimpleMPHIndex<Key, typename seeded_hash<HashFcn>::hash_function> index_;
|
||||||
// TODO(davi) optimize slack to use hash from index rather than calculate its own
|
// TODO(davi) optimize slack to use hash from index rather than calculate its own
|
||||||
typedef unordered_map<h128, uint32_t, h128::hash32> slack_type;
|
typedef unordered_map<h128, uint32_t, h128::hash32> slack_type;
|
||||||
@ -151,13 +153,13 @@ MPH_MAP_METHOD_DECL(void_type, pack)() {
|
|||||||
make_iterator_first(begin()),
|
make_iterator_first(begin()),
|
||||||
make_iterator_first(end()), size_);
|
make_iterator_first(end()), size_);
|
||||||
if (!success) { exit(-1); }
|
if (!success) { exit(-1); }
|
||||||
std::vector<value_type> new_values(index_.minimal_perfect_hash_size());
|
vector<value_type> new_values(index_.perfect_hash_size());
|
||||||
new_values.reserve(new_values.size() * 2);
|
new_values.reserve(new_values.size() * 2);
|
||||||
std::vector<bool> new_present(index_.minimal_perfect_hash_size(), false);
|
vector<bool> new_present(index_.perfect_hash_size(), false);
|
||||||
new_present.reserve(new_present.size() * 2);
|
new_present.reserve(new_present.size() * 2);
|
||||||
for (iterator it = begin(), it_end = end(); it != it_end; ++it) {
|
for (iterator it = begin(), it_end = end(); it != it_end; ++it) {
|
||||||
size_type id = index_.minimal_perfect_hash(it->first);
|
size_type id = index_.perfect_hash(it->first);
|
||||||
assert(id < index_.minimal_perfect_hash_size());
|
assert(id < index_.perfect_hash_size());
|
||||||
assert(id < new_values.size());
|
assert(id < new_values.size());
|
||||||
new_values[id] = *it;
|
new_values[id] = *it;
|
||||||
new_present[id] = true;
|
new_present[id] = true;
|
||||||
@ -168,10 +170,10 @@ MPH_MAP_METHOD_DECL(void_type, pack)() {
|
|||||||
slack_type().swap(slack_);
|
slack_type().swap(slack_);
|
||||||
}
|
}
|
||||||
|
|
||||||
MPH_MAP_METHOD_DECL(iterator, begin)() { return values_.begin(); }
|
MPH_MAP_METHOD_DECL(iterator, begin)() { return make_hollow(&values_, &present_, values_.begin()); }
|
||||||
MPH_MAP_METHOD_DECL(iterator, end)() { return values_.end(); }
|
MPH_MAP_METHOD_DECL(iterator, end)() { return make_solid(&values_, &present_, values_.end()); }
|
||||||
MPH_MAP_METHOD_DECL(const_iterator, begin)() const { return values_.begin(); }
|
MPH_MAP_METHOD_DECL(const_iterator, begin)() const { return make_hollow(&values_, &present_, values_.begin()); }
|
||||||
MPH_MAP_METHOD_DECL(const_iterator, end)() const { return values_.end(); }
|
MPH_MAP_METHOD_DECL(const_iterator, end)() const { return make_solid(&values_, &present_, values_.end()); }
|
||||||
MPH_MAP_METHOD_DECL(bool_type, empty)() const { return size_ == 0; }
|
MPH_MAP_METHOD_DECL(bool_type, empty)() const { return size_ == 0; }
|
||||||
MPH_MAP_METHOD_DECL(size_type, size)() const { return size_; }
|
MPH_MAP_METHOD_DECL(size_type, size)() const { return size_; }
|
||||||
|
|
||||||
@ -184,7 +186,7 @@ MPH_MAP_METHOD_DECL(void_type, clear)() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MPH_MAP_METHOD_DECL(void_type, erase)(iterator pos) {
|
MPH_MAP_METHOD_DECL(void_type, erase)(iterator pos) {
|
||||||
present_[pos - begin] = false;
|
present_[pos.it_ - begin().it_] = false;
|
||||||
*pos = value_type();
|
*pos = value_type();
|
||||||
--size_;
|
--size_;
|
||||||
}
|
}
|
||||||
@ -196,16 +198,16 @@ MPH_MAP_METHOD_DECL(void_type, erase)(const key_type& k) {
|
|||||||
|
|
||||||
MPH_MAP_INLINE_METHOD_DECL(const_iterator, find)(const key_type& k) const {
|
MPH_MAP_INLINE_METHOD_DECL(const_iterator, find)(const key_type& k) const {
|
||||||
auto idx = index(k);
|
auto idx = index(k);
|
||||||
auto it = begin() + idx;
|
typename vector<value_type>::const_iterator vit = values_.begin() + idx;
|
||||||
if (idx == -1 || it->first != k) return end();
|
if (idx == -1 || vit->first != k) return end();
|
||||||
return it;
|
return make_solid(&values_, &present_, vit);;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPH_MAP_INLINE_METHOD_DECL(iterator, find)(const key_type& k) {
|
MPH_MAP_INLINE_METHOD_DECL(iterator, find)(const key_type& k) {
|
||||||
auto idx = index(k);
|
auto idx = index(k);
|
||||||
auto it = begin() + idx;
|
typename vector<value_type>::iterator vit = values_.begin() + idx;
|
||||||
if (idx == -1 || it->first != k) return end();
|
if (idx == -1 || vit->first != k) return end();
|
||||||
return it;
|
return make_solid(&values_, &present_, vit);;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPH_MAP_INLINE_METHOD_DECL(my_int32_t, index)(const key_type& k) const {
|
MPH_MAP_INLINE_METHOD_DECL(my_int32_t, index)(const key_type& k) const {
|
||||||
@ -213,10 +215,10 @@ MPH_MAP_INLINE_METHOD_DECL(my_int32_t, index)(const key_type& k) const {
|
|||||||
auto sit = slack_.find(hasher128_.hash128(k, 0));
|
auto sit = slack_.find(hasher128_.hash128(k, 0));
|
||||||
if (sit != slack_.end()) return sit->second;
|
if (sit != slack_.end()) return sit->second;
|
||||||
}
|
}
|
||||||
if (__builtin_expect(index_.minimal_perfect_hash_size(), 1)) {
|
if (__builtin_expect(index_.perfect_hash_size(), 1)) {
|
||||||
auto minimal_perfect_hash = index_.minimal_perfect_hash(k);
|
auto perfect_hash = index_.perfect_hash(k);
|
||||||
if (__builtin_expect(present_[minimal_perfect_hash], true)) {
|
if (__builtin_expect(present_[perfect_hash], true)) {
|
||||||
return minimal_perfect_hash;
|
return perfect_hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user