Better.
This commit is contained in:
parent
5fab722781
commit
7ead7bff2f
|
@ -2,6 +2,20 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility> // for std::pair
|
#include <utility> // for std::pair
|
||||||
|
|
||||||
|
#include "MurmurHash2.h"
|
||||||
|
#include "mphtable.h"
|
||||||
|
#include "iterator_first.h"
|
||||||
|
|
||||||
|
namespace __gnu_cxx {
|
||||||
|
template <> struct hash<std::string> {
|
||||||
|
std::size_t operator()(std::string const& s) const {
|
||||||
|
return MurmurHash2(s.c_str(), s.length(), 1 /* seed */);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace cxxmph {
|
||||||
|
|
||||||
// Save on repetitive typing.
|
// Save on repetitive typing.
|
||||||
#define CMPH_TMPL_SPEC template <class Key, class Data, class HashFcn, class EqualKey, class Alloc>
|
#define CMPH_TMPL_SPEC template <class Key, class Data, class HashFcn, class EqualKey, class Alloc>
|
||||||
#define CMPH_CLASS_SPEC cmph_hash_map<Key, Data, HashFcn, EqualKey, Alloc>
|
#define CMPH_CLASS_SPEC cmph_hash_map<Key, Data, HashFcn, EqualKey, Alloc>
|
||||||
|
@ -51,7 +65,7 @@ class cmph_hash_map {
|
||||||
private:
|
private:
|
||||||
void rehash();
|
void rehash();
|
||||||
std::vector<value_type> values_;
|
std::vector<value_type> values_;
|
||||||
cmph_t* cmph_;
|
MPHTable table_;
|
||||||
typedef typename __gnu_cxx::hash_map<Key, Data, HashFcn, EqualKey, Alloc> slack_type;
|
typedef typename __gnu_cxx::hash_map<Key, Data, HashFcn, EqualKey, Alloc> slack_type;
|
||||||
slack_type slack_;
|
slack_type slack_;
|
||||||
};
|
};
|
||||||
|
@ -61,12 +75,11 @@ bool operator==(const CMPH_CLASS_SPEC& lhs, const CMPH_CLASS_SPEC& rhs) {
|
||||||
return lhs.values_ == rhs.values_;
|
return lhs.values_ == rhs.values_;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMPH_TMPL_SPEC CMPH_CLASS_SPEC::cmph_hash_map() : cmph_(NULL) {
|
CMPH_TMPL_SPEC CMPH_CLASS_SPEC::cmph_hash_map() {
|
||||||
rehash();
|
rehash();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMPH_TMPL_SPEC CMPH_CLASS_SPEC::~cmph_hash_map() {
|
CMPH_TMPL_SPEC CMPH_CLASS_SPEC::~cmph_hash_map() {
|
||||||
if(cmph_) cmph_destroy(cmph_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMPH_METHOD_DECL(insert_return_type, insert)(const value_type& x) {
|
CMPH_METHOD_DECL(insert_return_type, insert)(const value_type& x) {
|
||||||
|
@ -74,28 +87,22 @@ CMPH_METHOD_DECL(insert_return_type, insert)(const value_type& x) {
|
||||||
if (it != end()) return std::make_pair(it, false);
|
if (it != end()) return std::make_pair(it, false);
|
||||||
values_.push_back(x);
|
values_.push_back(x);
|
||||||
slack_.insert(std::make_pair(x.first, values_.size() - 1));
|
slack_.insert(std::make_pair(x.first, values_.size() - 1));
|
||||||
if ((slack_.size() > 10 && !cmph_) ||
|
if ((slack_.size() > 10 && table_.size() == 0) ||
|
||||||
(cmph_ && slack_.size() > cmph_size(cmph_) * 2)) rehash();
|
(table_.size() && slack_.size() > table_.size() * 2)) {
|
||||||
|
rehash();
|
||||||
|
}
|
||||||
it = find(x.first);
|
it = find(x.first);
|
||||||
// std::cerr << "inserted " << x.first.i_ << " at " << values_.begin() - it;
|
|
||||||
return std::make_pair(it, true);
|
return std::make_pair(it, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMPH_METHOD_DECL(void_type, rehash)() {
|
CMPH_METHOD_DECL(void_type, rehash)() {
|
||||||
if (values_.empty()) return;
|
if (values_.empty()) return;
|
||||||
slack_type().swap(slack_);
|
slack_type().swap(slack_);
|
||||||
cmph_io_adapter_t* source = cmph_io_struct_vector_adapter(
|
table_.Reset(make_iterator_first(values_.begin()),
|
||||||
&(values_[0]), sizeof(value_type), 0, sizeof(key_type), values_.size());
|
make_iterator_first(values_.end()));
|
||||||
cmph_config_t* cmph_config = cmph_config_new(source);
|
|
||||||
cmph_config_set_algo(cmph_config, CMPH_CHD);
|
|
||||||
// cmph_config_set_verbosity(cmph_config, 1);
|
|
||||||
if (cmph_) cmph_destroy(cmph_);
|
|
||||||
cmph_ = cmph_new(cmph_config);
|
|
||||||
cmph_config_destroy(cmph_config);
|
|
||||||
cmph_io_struct_vector_adapter_destroy(source);
|
|
||||||
std::vector<value_type> new_values(values_.size());
|
std::vector<value_type> new_values(values_.size());
|
||||||
for (int i = 0; i < values_.size(); ++i) {
|
for (unsigned int i = 0; i < values_.size(); ++i) {
|
||||||
size_type id = cmph_search(cmph_, reinterpret_cast<const char*>(&(values_[i].first)), sizeof(key_type));
|
size_type id = table_.index(values_[i].first);
|
||||||
new_values[id] = values_[i];
|
new_values[id] = values_[i];
|
||||||
}
|
}
|
||||||
values_.swap(new_values);
|
values_.swap(new_values);
|
||||||
|
@ -110,8 +117,7 @@ CMPH_METHOD_DECL(bool_type, empty)() const { return values_.empty(); }
|
||||||
CMPH_METHOD_DECL(void_type, clear)() {
|
CMPH_METHOD_DECL(void_type, clear)() {
|
||||||
values_.clear();
|
values_.clear();
|
||||||
slack_.clear();
|
slack_.clear();
|
||||||
cmph_destroy(cmph_);
|
table_.clear();
|
||||||
cmph_ = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMPH_METHOD_DECL(void_type, erase)(iterator pos) {
|
CMPH_METHOD_DECL(void_type, erase)(iterator pos) {
|
||||||
|
@ -129,9 +135,8 @@ CMPH_METHOD_DECL(const_iterator, find)(const key_type& k) const {
|
||||||
typename slack_type::const_iterator it = slack_.find(k);
|
typename slack_type::const_iterator it = slack_.find(k);
|
||||||
if (it != slack_.end()) return values_.begin() + it->second;
|
if (it != slack_.end()) return values_.begin() + it->second;
|
||||||
}
|
}
|
||||||
if (!cmph_) return end();
|
if (table_.size() == 0) return end();
|
||||||
size_type id = cmph_search(cmph_, reinterpret_cast<const char*>(&k),
|
size_type id = table_.index(k);
|
||||||
sizeof(key_type));
|
|
||||||
if (key_equal()(values_[id].first, k)) {
|
if (key_equal()(values_[id].first, k)) {
|
||||||
return values_.begin() + id;
|
return values_.begin() + id;
|
||||||
}
|
}
|
||||||
|
@ -142,9 +147,8 @@ CMPH_METHOD_DECL(iterator, find)(const key_type& k) {
|
||||||
typename slack_type::const_iterator it = slack_.find(k);
|
typename slack_type::const_iterator it = slack_.find(k);
|
||||||
if (it != slack_.end()) return values_.begin() + it->second;
|
if (it != slack_.end()) return values_.begin() + it->second;
|
||||||
}
|
}
|
||||||
if (!cmph_) return end();
|
if (table_.size() == 0) return end();
|
||||||
size_type id = cmph_search(cmph_, reinterpret_cast<const char*>(&k),
|
size_type id = table_.index(k);
|
||||||
sizeof(key_type));
|
|
||||||
if (key_equal()(values_[id].first, k)) {
|
if (key_equal()(values_[id].first, k)) {
|
||||||
return values_.begin() + id;
|
return values_.begin() + id;
|
||||||
}
|
}
|
||||||
|
@ -155,3 +159,5 @@ CMPH_METHOD_DECL(iterator, find)(const key_type& k) {
|
||||||
CMPH_METHOD_DECL(data_type&, operator[])(const key_type& k) {
|
CMPH_METHOD_DECL(data_type&, operator[])(const key_type& k) {
|
||||||
return insert(std::make_pair(k, data_type())).first->second;
|
return insert(std::make_pair(k, data_type())).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace cxxmph
|
||||||
|
|
|
@ -1,18 +1,30 @@
|
||||||
#include "cmph_hash_map.h"
|
#include "cmph_hash_map.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using cxxmph::cmph_hash_map;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
cmph_hash_map<int, int> h;
|
cmph_hash_map<string, int> h;
|
||||||
h.insert(std::make_pair(-1,-1));
|
h.insert(std::make_pair("-1",-1));
|
||||||
for (cmph_hash_map<int, int>::const_iterator it = h.begin(); it != h.end(); ++it) {
|
cmph_hash_map<string, int>::const_iterator it;
|
||||||
|
for (it = h.begin(); it != h.end(); ++it) {
|
||||||
std::cout << it->first << " -> " << it->second << std::endl;
|
std::cout << it->first << " -> " << it->second << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << "Search -1 gives " << h.find(-1)->second << std::endl;
|
std::cout << "Search -1 gives " << h.find("-1")->second << std::endl;
|
||||||
for (int i = 0; i < 1000; ++i) h.insert(std::make_pair(i, i));
|
for (int i = 0; i < 1000; ++i) {
|
||||||
|
char buf[10];
|
||||||
|
snprintf(buf, 10, "%d", i);
|
||||||
|
h.insert(std::make_pair(buf, i));
|
||||||
|
}
|
||||||
for (int j = 0; j < 1000; ++j) {
|
for (int j = 0; j < 1000; ++j) {
|
||||||
for (int i = 1000; i > 0; --i) {
|
for (int i = 1000; i > 0; --i) {
|
||||||
h.find(i - 1);
|
char buf[10];
|
||||||
|
snprintf(buf, 10, "%d", i - 1);
|
||||||
|
h.find(buf);
|
||||||
// std::cout << "Search " << i - 1 << " gives " << h.find(i - 1)->second << std::endl;
|
// std::cout << "Search " << i - 1 << " gives " << h.find(i - 1)->second << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,9 @@ cmph_uint32 get_2bit_value(const vector<cmph_uint8>& d, cmph_uint8 i) {
|
||||||
|
|
||||||
namespace cxxmph {
|
namespace cxxmph {
|
||||||
|
|
||||||
|
void MPHTable::clear() {
|
||||||
|
// TODO(davi) impolement me
|
||||||
|
}
|
||||||
bool MPHTable::GenerateQueue(
|
bool MPHTable::GenerateQueue(
|
||||||
TriGraph* graph, vector<cmph_uint32>* queue_output) {
|
TriGraph* graph, vector<cmph_uint32>* queue_output) {
|
||||||
cmph_uint32 queue_head = 0, queue_tail = 0;
|
cmph_uint32 queue_head = 0, queue_tail = 0;
|
||||||
|
|
|
@ -30,6 +30,8 @@ class MPHTable {
|
||||||
template <class ForwardIterator>
|
template <class ForwardIterator>
|
||||||
bool Reset(ForwardIterator begin, ForwardIterator end);
|
bool Reset(ForwardIterator begin, ForwardIterator end);
|
||||||
cmph_uint32 index(const key_type& x) const;
|
cmph_uint32 index(const key_type& x) const;
|
||||||
|
cmph_uint32 size() const { return m_; }
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class ForwardIterator>
|
template <class ForwardIterator>
|
||||||
|
|
Loading…
Reference in New Issue