Compiles with clang.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
TESTS = $(check_PROGRAMS)
|
||||
check_PROGRAMS = seeded_hash_test mph_bits_test hollow_iterator_test mph_map_test mph_index_test trigraph_test map_tester_test
|
||||
check_PROGRAMS = seeded_hash_test mph_bits_test hollow_iterator_test mph_map_test mph_index_test trigraph_test map_tester_test string_util_test
|
||||
noinst_PROGRAMS = bm_index bm_map
|
||||
bin_PROGRAMS = cxxmph
|
||||
lib_LTLIBRARIES = libcxxmph.la
|
||||
libcxxmph_la_SOURCES = MurmurHash3.h MurmurHash3.cpp trigragh.h trigraph.cc mph_bits.h mph_bits.cc mph_index.h mph_index.cc seeded_hash.h stringpiece.h benchmark.h benchmark.cc
|
||||
libcxxmph_la_SOURCES = MurmurHash3.h MurmurHash3.cpp trigragh.h trigraph.cc mph_bits.h mph_bits.cc mph_index.h mph_index.cc seeded_hash.h stringpiece.h benchmark.h benchmark.cc string_util.cc
|
||||
libcxxmph_la_LDFLAGS = -version-info 0:0:0
|
||||
cxxmph_includedir = $(includedir)/cxxmph/
|
||||
cxxmph_include_HEADERS = mph_map.h mph_index.h MurmurHash3.h trigraph.h seeded_hash.h stringpiece.h hollow_iterator.h
|
||||
@@ -34,5 +34,8 @@ seeded_hash_test_LDADD = libcxxmph.la
|
||||
mph_bits_test_SOURCES = mph_bits_test.cc
|
||||
mph_bits_test_LDADD = libcxxmph.la
|
||||
|
||||
string_util_test_SOURCES = string_util_test.cc
|
||||
string_util_test_LDADD = libcxxmph.la
|
||||
|
||||
map_tester_test_SOURCES = map_tester.cc map_tester_test.cc
|
||||
|
||||
|
||||
@@ -44,10 +44,12 @@ class BM_MPHIndexSearch : public SearchUrlsBenchmark {
|
||||
BM_MPHIndexSearch(const std::string& urls_file, int nsearches)
|
||||
: SearchUrlsBenchmark(urls_file, nsearches, 0) { }
|
||||
virtual void Run() {
|
||||
uint64_t sum = 0;
|
||||
for (auto it = random_.begin(); it != random_.end(); ++it) {
|
||||
auto idx = index_.index(*it);
|
||||
// Collision check to be fair with STL
|
||||
if (strcmp(urls_[idx].c_str(), it->data()) != 0) idx = -1;
|
||||
sum += idx;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
@@ -65,10 +67,12 @@ class BM_CmphIndexSearch : public SearchUrlsBenchmark {
|
||||
: SearchUrlsBenchmark(urls_file, nsearches, 0) { }
|
||||
~BM_CmphIndexSearch() { if (index_) cmph_destroy(index_); }
|
||||
virtual void Run() {
|
||||
uint64_t sum = 0;
|
||||
for (auto it = random_.begin(); it != random_.end(); ++it) {
|
||||
auto idx = cmph_search(index_, it->data(), it->length());
|
||||
// Collision check to be fair with STL
|
||||
if (strcmp(urls_[idx].c_str(), it->data()) != 0) idx = -1;
|
||||
sum += idx;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
@@ -114,8 +118,10 @@ class BM_STLIndexSearch : public SearchUrlsBenchmark {
|
||||
BM_STLIndexSearch(const std::string& urls_file, int nsearches)
|
||||
: SearchUrlsBenchmark(urls_file, nsearches, 0) { }
|
||||
virtual void Run() {
|
||||
uint64_t sum = 0;
|
||||
for (auto it = random_.begin(); it != random_.end(); ++it) {
|
||||
auto idx = index_.find(*it);
|
||||
sum += idx->second;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <string>
|
||||
#include <tr1/unordered_map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "bm_common.h"
|
||||
#include "mph_map.h"
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
#include "map_tester.h"
|
||||
|
||||
namespace cxxxmph {
|
||||
|
||||
MapTester::MapTester() {}
|
||||
MapTester::~MapTester() {}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,15 +7,18 @@
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "string_util.h"
|
||||
|
||||
namespace cxxmph {
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <template <class K, class V> class unordered_map> >
|
||||
template <template<typename...> class map_type>
|
||||
class MapTester {
|
||||
public:
|
||||
MapTester();
|
||||
~MapTester();
|
||||
MapTester() {}
|
||||
~MapTester() {}
|
||||
|
||||
bool Run(string* errors) const {
|
||||
string e;
|
||||
if (!small_insert()) e += "small insert failed\n";
|
||||
@@ -27,26 +30,26 @@ class MapTester {
|
||||
return !e.empty();
|
||||
}
|
||||
static bool small_insert() {
|
||||
unordered_map<int64_t, int64_t> m;
|
||||
map_type<int64_t, int64_t> m;
|
||||
// Start counting from 1 to not touch default constructed value bugs
|
||||
for (int i = 1; i < 12; ++i) m.insert(make_pair(i, i));
|
||||
return m.size() == 11;
|
||||
}
|
||||
static bool large_insert() {
|
||||
unordered_map<int64_t, int64_t> m;
|
||||
map_type<int64_t, int64_t> m;
|
||||
// Start counting from 1 to not touch default constructed value bugs
|
||||
for (int i = 1; i < 12 * 256 * 256; ++i) m.insert(make_pair(i, i));
|
||||
return m.size() == 12 * 256 * 256 - 1;
|
||||
}
|
||||
static bool small_search() {
|
||||
unordered_map<int64_t, int64_t> m;
|
||||
map_type<int64_t, int64_t> m;
|
||||
// Start counting from 1 to not touch default constructed value bugs
|
||||
for (int i = 1; i < 12; ++i) m.insert(make_pair(i, i));
|
||||
for (int i = 1; i < 12; ++i) if (m.find(i) == m.end()) return false;
|
||||
return true;
|
||||
}
|
||||
static bool default_search() {
|
||||
unordered_map<int64_t, int64_t> m;
|
||||
map_type<int64_t, int64_t> m;
|
||||
if (m.find(0) != m.end()) return false;
|
||||
for (int i = 1; i < 256; ++i) m.insert(make_pair(i, i));
|
||||
if (m.find(0) != m.end()) return false;
|
||||
@@ -56,7 +59,7 @@ class MapTester {
|
||||
}
|
||||
static bool large_search() {
|
||||
int nkeys = 10 * 1000;
|
||||
unordered_map<int64_t, int64_t> m;
|
||||
map_type<int64_t, int64_t> m;
|
||||
for (int i = 0; i < nkeys; ++i) m.insert(make_pair(i, i));
|
||||
for (int i = 0; i < nkeys; ++i) if (m.find(i) == m.end()) return false;
|
||||
return true;
|
||||
@@ -66,10 +69,10 @@ class MapTester {
|
||||
vector<string> keys;
|
||||
for (int i = 0; i < nkeys; ++i) {
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "%lu", i);
|
||||
cxxmph::format("%v", i);
|
||||
keys.push_back(buf);
|
||||
}
|
||||
unordered_map<string, int64_t> m;
|
||||
map_type<string, int64_t> m;
|
||||
for (int i = 0; i < nkeys; ++i) m.insert(make_pair(keys[i], i));
|
||||
for (int i = 0; i < nkeys; ++i) {
|
||||
auto it = m.find(keys[i]);
|
||||
|
||||
23
cxxmph/string_util.cc
Normal file
23
cxxmph/string_util.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "string_util.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cxxmph {
|
||||
|
||||
bool stream_printf(
|
||||
const std::string& format_string, uint32_t offset, std::ostream* out) {
|
||||
if (offset == format_string.length()) return true;
|
||||
assert(offset < format_string.length());
|
||||
cerr << "length:" << format_string.length() << endl;
|
||||
cerr << "offset:" << offset << endl;
|
||||
auto txt = format_string.substr(offset, format_string.length() - offset);
|
||||
*out << txt;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cxxmph
|
||||
137
cxxmph/string_util.h
Normal file
137
cxxmph/string_util.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef __CXXMPH_STRING_UTIL_H__
|
||||
#define __CXXMPH_STRING_UTIL_H__
|
||||
|
||||
// Helper functions for string formatting and terminal output. Should be used
|
||||
// only for debugging and tests, since performance was not a concern.
|
||||
// Implemented using variadic templates because it is cool.
|
||||
//
|
||||
// Adds the extra format %v to the printf formatting language. Uses the method
|
||||
// cxxmph::tostr to implement custom printers and fallback to operator
|
||||
// ostream::operator<< otherwise.
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#define CXXMPH_DEBUGLN(fmt) variadic_print(__FILE__, __LINE__, &std::cerr, fmt)
|
||||
#define CXXMPH_INFOLN(fmt) variadic_print(__FILE__, __LINE__, &std::cout, fmt)
|
||||
|
||||
namespace cxxmph {
|
||||
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
using std::vector;
|
||||
|
||||
template <class T> void tostr(ostream *out, const T& v) {
|
||||
*out << v;
|
||||
}
|
||||
inline void tostr(std::ostream* out, uint8_t v) {
|
||||
*out << static_cast<uint32_t>(v);
|
||||
}
|
||||
template <class V>
|
||||
inline void tostr(ostream* out, const vector<V>& v) {
|
||||
*out << "[";
|
||||
for (uint32_t i = 0; i < v.size(); ++i) {
|
||||
tostr(out, v[1]);
|
||||
if (i != v.size() - 1)*out << " ";
|
||||
}
|
||||
*out << "]";
|
||||
}
|
||||
template <class F, class S>
|
||||
inline void tostr(ostream* out, const pair<F, S>& v) {
|
||||
*out << "(";
|
||||
tostr(out, v.first);
|
||||
*out << ",";
|
||||
tostr(out, v.second);
|
||||
*out << ")";
|
||||
}
|
||||
|
||||
template <typename... Args, class T >
|
||||
std::string infoln(const std::string& format_string, Args&&... args) {
|
||||
return stream_printf(format_string, 0, &std::cout, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
bool stream_printf(
|
||||
const std::string& format_string, uint32_t offset, std::ostream* out);
|
||||
|
||||
template <bool ispod> struct pod_snprintf {};
|
||||
template <> struct pod_snprintf<false> {
|
||||
template <class T>
|
||||
int operator()(char*, size_t, const char*, const T&) {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
template <> struct pod_snprintf<true> {
|
||||
template <class T>
|
||||
int operator()(char* str, size_t size, const char* format, const T& v) {
|
||||
return snprintf(str, size, format, v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
bool stream_printf(const std::string& format_string, uint32_t offset,
|
||||
std::ostream* out, const T& value, Args&&... args) {
|
||||
auto b = format_string.c_str() + offset;
|
||||
auto txt = format_string.c_str() + offset;
|
||||
for (; *txt; ++txt) {
|
||||
if (*txt == '%') {
|
||||
if (*(txt + 1) != '%') break;
|
||||
*out << "%";
|
||||
return stream_printf(format_string, offset + 2, out, value,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
if (txt != b) {
|
||||
*out << string(b, txt - b);
|
||||
}
|
||||
auto fmt = txt + 1;
|
||||
while (*fmt && *fmt != '%') ++fmt;
|
||||
if (strncmp(txt, "%v", 2) == 0) {
|
||||
txt += 2;
|
||||
tostr(out, value);
|
||||
if (txt != fmt) *out << string(txt, fmt);
|
||||
} else {
|
||||
char buf[256]; // Is this enough?
|
||||
auto n = pod_snprintf<std::is_pod<T>::value>()(
|
||||
buf, 256, std::string(txt, fmt).c_str(), value);
|
||||
if (n < 0) return false;
|
||||
*out << buf;
|
||||
}
|
||||
return stream_printf(format_string, fmt - format_string.c_str(), out,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string format(const std::string& format_string, Args&&... args) {
|
||||
std::ostringstream out;
|
||||
if (!stream_printf(format_string, 0, &out, std::forward<Args>(args)...)) {
|
||||
return std::string();
|
||||
};
|
||||
return out.str();
|
||||
}
|
||||
|
||||
struct variadic_print {
|
||||
variadic_print(const std::string& file, uint32_t line, std::ostream* out,
|
||||
const std::string& format_line)
|
||||
: file_(file), line_(line), out_(out), format_line_(format_line) {}
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args) {
|
||||
std::string fancy_format = "%s:%d: ";
|
||||
fancy_format += format_line_;
|
||||
stream_printf(fancy_format, 0, out_, std::forward<Args>(args)...);
|
||||
}
|
||||
const std::string& file_;
|
||||
const uint32_t& line_;
|
||||
std::ostream* out_;
|
||||
const std::string& format_line_;
|
||||
};
|
||||
|
||||
} // namespace cxxmph
|
||||
|
||||
#endif // __CXXMPH_STRING_UTIL_H__
|
||||
Reference in New Issue
Block a user