Fixed compilation error and detected iterator problem.

This commit is contained in:
Davi de Castro Reis 2010-11-05 21:46:53 -02:00
parent c09df518dc
commit 0c5f2301df
4 changed files with 89 additions and 19 deletions

View File

@ -1,4 +1,5 @@
bin_PROGRAMS = cmph_hash_map_test mphtable_test trigraph_test noinst_PROGRAMS = cmph_hash_map_test mphtable_test trigraph_test
bin_PROGRAMS = cxxmph
lib_LTLIBRARIES = libcxxmph.la lib_LTLIBRARIES = libcxxmph.la
include_HEADERS = cmph_hash_map.h mphtable.h MurmurHash2.h trigraph.h cmph_hash_function.h stringpiece.h include_HEADERS = cmph_hash_map.h mphtable.h MurmurHash2.h trigraph.h cmph_hash_function.h stringpiece.h
@ -13,3 +14,6 @@ mphtable_test_SOURCES = mphtable_test.cc
trigraph_test_LDADD = libcxxmph.la trigraph_test_LDADD = libcxxmph.la
trigraph_test_SOURCES = trigraph_test.cc trigraph_test_SOURCES = trigraph_test.cc
cxxmph_LDADD = libcxxmph.la
cxxmph_SOURCES = cxxmph.cc

View File

@ -5,27 +5,14 @@
#include "MurmurHash2.h" #include "MurmurHash2.h"
#include "mphtable.h" #include "mphtable.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 */);
}
};
template <> struct hash<long long int> {
std::size_t operator()(const long long int& s) const {
return MurmurHash2(reinterpret_cast<const char*>(&s), sizeof(long long int), 1 /* seed */);
}
};
} // namespace __gnu_cxx
namespace cxxmph { 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>
#define CMPH_METHOD_DECL(r, m) CMPH_TMPL_SPEC typename CMPH_CLASS_SPEC::r CMPH_CLASS_SPEC::m #define CMPH_METHOD_DECL(r, m) CMPH_TMPL_SPEC typename CMPH_CLASS_SPEC::r CMPH_CLASS_SPEC::m
template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key>, class EqualKey = std::equal_to<Key>, class Alloc = std::allocator<Data> > template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key>, class EqualKey = std::equal_to<Key>, class Alloc = std::allocator<Data> >
class cmph_hash_map { class cmph_hash_map {
public: public:
typedef Key key_type; typedef Key key_type;
@ -132,10 +119,10 @@ CMPH_METHOD_DECL(const_iterator, begin)() const { return values_.begin(); }
CMPH_METHOD_DECL(const_iterator, end)() const { return values_.end(); } CMPH_METHOD_DECL(const_iterator, end)() const { return values_.end(); }
CMPH_METHOD_DECL(bool_type, empty)() const { return values_.empty(); } 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();
table_.clear(); table_.clear();
} }
CMPH_METHOD_DECL(void_type, erase)(iterator pos) { CMPH_METHOD_DECL(void_type, erase)(iterator pos) {
@ -163,6 +150,8 @@ CMPH_METHOD_DECL(const_iterator, find)(const key_type& k) const {
CMPH_METHOD_DECL(iterator, find)(const key_type& k) { CMPH_METHOD_DECL(iterator, find)(const key_type& k) {
if (!slack_.empty()) { if (!slack_.empty()) {
typename slack_type::const_iterator it = slack_.find(k); typename slack_type::const_iterator it = slack_.find(k);
// TODO(davi) this is broken, it->second should be an integer
// otherwise I cannot access values_ iterators.
if (it != slack_.end()) return values_.begin() + it->second; if (it != slack_.end()) return values_.begin() + it->second;
} }
if (table_.size() == 0) return end(); if (table_.size() == 0) return end();
@ -172,7 +161,6 @@ CMPH_METHOD_DECL(iterator, find)(const key_type& k) {
} }
return end(); return end();
} }
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;

View File

@ -1,5 +1,6 @@
#include "cmph_hash_map.h" #include "cmph_hash_map.h"
#include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -28,4 +29,13 @@ int main(int argc, char** argv) {
std::cerr << "Search " << i - 1 << " gives " << h.find(buf)->second << std::endl; std::cerr << "Search " << i - 1 << " gives " << h.find(buf)->second << std::endl;
} }
} }
for (int j = 0; j < 100; ++j) {
for (int i = 1000; i > 0; --i) {
char buf[10];
snprintf(buf, 10, "%d", i*100 - 1);
h.find(buf);
std::cerr << "Search " << i*100 - 1 << " gives " << h.find(buf)->second << std::endl;
}
}
} }

68
cxxmph/cxxmph.cc Normal file
View File

@ -0,0 +1,68 @@
// Copyright 2010 Google Inc. All Rights Reserved.
// Author: davi@google.com (Davi Reis)
#include <getopt.h>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "cmph_hash_map.h"
#include "config.h"
using std::cerr;
using std::cout;
using std::endl;
using std::getline;
using std::ifstream;
using std::string;
using std::vector;
using cxxmph::cmph_hash_map;
void usage(const char* prg) {
cerr << "usage: " << prg << "[-v] [-h] [-V]" << endl;
}
void usage_long(const char* prg) {
usage(prg);
cerr << " -h\t print this help message" << endl;
cerr << " -V\t print version number and exit" << endl;
cerr << " -v\t increase verbosity (may be used multiple times)" << endl;
}
int main(int argc, char** argv) {
int verbosity = 0;
while (1) {
char ch = (char)getopt(argc, argv, "hv");
if (ch == -1) break;
switch (ch) {
case 'h':
usage_long(argv[0]);
return 0;
case 'V':
std::cout << VERSION << std::endl;
return 0;
case 'v':
++verbosity;
break;
}
}
if (optind != argc - 1) {
usage(argv[0]);
return 1;
}
vector<string> keys;
ifstream f(argv[optind]);
string buffer;
while (!getline(f, buffer).eof()) keys.push_back(buffer);
cmph_hash_map<const char*, string> table;
for (int i = 0; i < keys.size(); ++i) table[keys[i].c_str()] = keys[i];
cmph_hash_map<const char*, string>::const_iterator it = table.begin();
cmph_hash_map<const char*, string>::const_iterator end = table.end();
for (; it != end; ++it) {
cout << (it - table.begin()) << ": " << it->first
<<" -> " << it->second << endl;
}
}