All tests pass.
This commit is contained in:
parent
bcf4962604
commit
48155e5b66
@ -21,8 +21,8 @@ fi
|
||||
if test "x$ac_cv_sys_largefile_LIBS" = "xno" ; then
|
||||
ac_cv_sys_largefile_LIBS=""
|
||||
fi
|
||||
CFLAGS="$CFLAGS $ac_cv_sys_largefile_CFLAGS"
|
||||
LDFLAGS="$LDFLAGS $ac_cv_sys_largefile_LDFLAGS"
|
||||
CFLAGS="$$ac_cv_sys_largefile_CFLAGS $CFLAGS"
|
||||
LDFLAGS="$ac_cv_sys_largefile_LDFLAGS $LDFLAGS"
|
||||
LIBS="$LIBS $ac_cv_sys_largefile_LIBS"
|
||||
|
||||
dnl Checks for headers
|
||||
@ -34,6 +34,7 @@ LDFLAGS="$LIBM $LDFLAGS"
|
||||
CFLAGS="-Wall -Werror"
|
||||
|
||||
AC_PROG_CXX
|
||||
CXXFLAGS="-Wall -Winline -Wno-unused-function -Werror -DNDEBUG -O3 -fomit-frame-pointer $CXXFLAGS"
|
||||
AC_ENABLE_CXXMPH
|
||||
if test x$cxxmph = xtrue; then
|
||||
AC_COMPILE_STDCXX_0X
|
||||
|
@ -3,7 +3,7 @@ check_PROGRAMS = seeded_hash_test mph_bits_test hollow_iterator_test mph_map_tes
|
||||
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_index.h mph_index.cc seeded_hash.h stringpiece.h benchmark.h benchmark.cc mph_bits.h mph_bits.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
|
||||
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
|
||||
|
@ -106,7 +106,7 @@ namespace cxxmph {
|
||||
}
|
||||
|
||||
/* static */ void Benchmark::RunAll() {
|
||||
for (int i = 0; i < g_benchmarks.size(); ++i) {
|
||||
for (uint32_t i = 0; i < g_benchmarks.size(); ++i) {
|
||||
std::auto_ptr<Benchmark> bm(g_benchmarks[i]);
|
||||
if (!bm->SetUp()) {
|
||||
cerr << "Set up phase for benchmark "
|
||||
|
@ -14,6 +14,7 @@ using std::vector;
|
||||
|
||||
namespace cxxmph {
|
||||
|
||||
UrlsBenchmark::~UrlsBenchmark() {}
|
||||
bool UrlsBenchmark::SetUp() {
|
||||
vector<string> urls;
|
||||
std::ifstream f(urls_file_.c_str());
|
||||
@ -32,12 +33,13 @@ bool UrlsBenchmark::SetUp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
SearchUrlsBenchmark::~SearchUrlsBenchmark() {}
|
||||
bool SearchUrlsBenchmark::SetUp() {
|
||||
if (!UrlsBenchmark::SetUp()) return false;
|
||||
int32_t miss_ratio_int32 = std::numeric_limits<int32_t>::max() * miss_ratio_;
|
||||
forced_miss_urls_.resize(nsearches_);
|
||||
random_.resize(nsearches_);
|
||||
for (int i = 0; i < nsearches_; ++i) {
|
||||
for (uint32_t i = 0; i < nsearches_; ++i) {
|
||||
random_[i] = urls_[random() % urls_.size()];
|
||||
if (random() < miss_ratio_int32) {
|
||||
forced_miss_urls_[i] = random_[i].as_string() + ".force_miss";
|
||||
@ -47,9 +49,10 @@ bool SearchUrlsBenchmark::SetUp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
Uint64Benchmark::~Uint64Benchmark() {}
|
||||
bool Uint64Benchmark::SetUp() {
|
||||
set<uint64_t> unique;
|
||||
for (int i = 0; i < count_; ++i) {
|
||||
for (uint32_t i = 0; i < count_; ++i) {
|
||||
uint64_t v;
|
||||
do { v = random(); } while (unique.find(v) != unique.end());
|
||||
values_.push_back(v);
|
||||
@ -58,10 +61,11 @@ bool Uint64Benchmark::SetUp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
SearchUint64Benchmark::~SearchUint64Benchmark() {}
|
||||
bool SearchUint64Benchmark::SetUp() {
|
||||
if (!Uint64Benchmark::SetUp()) return false;
|
||||
random_.resize(nsearches_);
|
||||
for (int i = 0; i < nsearches_; ++i) {
|
||||
for (uint32_t i = 0; i < nsearches_; ++i) {
|
||||
uint32_t pos = random() % values_.size();
|
||||
random_[i] = values_[pos];
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace cxxmph {
|
||||
class UrlsBenchmark : public Benchmark {
|
||||
public:
|
||||
UrlsBenchmark(const std::string& urls_file) : urls_file_(urls_file) { }
|
||||
virtual ~UrlsBenchmark() {}
|
||||
virtual ~UrlsBenchmark();
|
||||
protected:
|
||||
virtual bool SetUp();
|
||||
const std::string urls_file_;
|
||||
@ -36,7 +36,7 @@ class SearchUrlsBenchmark : public UrlsBenchmark {
|
||||
public:
|
||||
SearchUrlsBenchmark(const std::string& urls_file, uint32_t nsearches, float miss_ratio)
|
||||
: UrlsBenchmark(urls_file), nsearches_(nsearches), miss_ratio_(miss_ratio) {}
|
||||
virtual ~SearchUrlsBenchmark() {}
|
||||
virtual ~SearchUrlsBenchmark();
|
||||
protected:
|
||||
virtual bool SetUp();
|
||||
const uint32_t nsearches_;
|
||||
@ -48,6 +48,7 @@ class SearchUrlsBenchmark : public UrlsBenchmark {
|
||||
class Uint64Benchmark : public Benchmark {
|
||||
public:
|
||||
Uint64Benchmark(uint32_t count) : count_(count) { }
|
||||
virtual ~Uint64Benchmark();
|
||||
virtual void Run() {}
|
||||
protected:
|
||||
virtual bool SetUp();
|
||||
@ -59,6 +60,7 @@ class SearchUint64Benchmark : public Uint64Benchmark {
|
||||
public:
|
||||
SearchUint64Benchmark(uint32_t count, uint32_t nsearches)
|
||||
: Uint64Benchmark(count), nsearches_(nsearches) { }
|
||||
virtual ~SearchUint64Benchmark();
|
||||
virtual void Run() {};
|
||||
protected:
|
||||
virtual bool SetUp();
|
||||
|
@ -47,7 +47,7 @@ class BM_MPHIndexSearch : public SearchUrlsBenchmark {
|
||||
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;
|
||||
if (strcmp(urls_[idx].c_str(), it->data()) != 0) idx = -1;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
|
@ -42,7 +42,7 @@ class BM_SearchUrls : public SearchUrlsBenchmark {
|
||||
virtual ~BM_SearchUrls() {}
|
||||
virtual void Run() {
|
||||
for (auto it = random_.begin(); it != random_.end(); ++it) {
|
||||
auto v = myfind(mymap_, *it);
|
||||
myfind(mymap_, *it);
|
||||
assert(it->ends_with(".force_miss") ^ v != NULL);
|
||||
assert(!v || *v == *it);
|
||||
}
|
||||
@ -66,12 +66,12 @@ class BM_SearchUint64 : public SearchUint64Benchmark {
|
||||
BM_SearchUint64() : SearchUint64Benchmark(100000, 10*1000*1000) { }
|
||||
virtual bool SetUp() {
|
||||
if (!SearchUint64Benchmark::SetUp()) return false;
|
||||
for (int i = 0; i < values_.size(); ++i) {
|
||||
for (uint32_t i = 0; i < values_.size(); ++i) {
|
||||
mymap_[values_[i]] = values_[i];
|
||||
}
|
||||
mymap_.rehash(mymap_.bucket_count());
|
||||
// Double check if everything is all right
|
||||
for (int i = 0; i < values_.size(); ++i) {
|
||||
for (uint32_t i = 0; i < values_.size(); ++i) {
|
||||
if (mymap_[values_[i]] != values_[i]) return false;
|
||||
}
|
||||
return true;
|
||||
@ -80,7 +80,7 @@ class BM_SearchUint64 : public SearchUint64Benchmark {
|
||||
for (auto it = random_.begin(); it != random_.end(); ++it) {
|
||||
auto v = myfind(mymap_, *it);
|
||||
if (*v != *it) {
|
||||
fprintf(stderr, "Looked for %lu got %lu\n", *it, *v);
|
||||
fprintf(stderr, "Looked for %llu got %llu\n", *it, *v);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
@ -57,10 +57,10 @@ int main(int argc, char** argv) {
|
||||
ifstream f(argv[optind]);
|
||||
string buffer;
|
||||
while (!getline(f, buffer).eof()) keys.push_back(buffer);
|
||||
for (int i = 0; i < keys.size(); ++i) string s = keys[i];
|
||||
for (uint32_t i = 0; i < keys.size(); ++i) string s = keys[i];
|
||||
mph_map<string, string> table;
|
||||
|
||||
for (int i = 0; i < keys.size(); ++i) table[keys[i]] = keys[i];
|
||||
for (uint32_t i = 0; i < keys.size(); ++i) table[keys[i]] = keys[i];
|
||||
mph_map<string, string>::const_iterator it = table.begin();
|
||||
mph_map<string, string>::const_iterator end = table.end();
|
||||
for (int i = 0; it != end; ++it, ++i) {
|
||||
|
@ -5,66 +5,65 @@
|
||||
|
||||
namespace cxxmph {
|
||||
|
||||
template <typename container_type, typename presence_type, typename iterator_type>
|
||||
using std::vector;
|
||||
|
||||
template <typename container_type>
|
||||
struct is_empty {
|
||||
public:
|
||||
is_empty() : c_(NULL), p_(NULL) {};
|
||||
is_empty(const container_type* c, const vector<bool>* p) : c_(c), p_(p) {};
|
||||
bool operator()(typename container_type::const_iterator it) const {
|
||||
if (it == c_->end()) return false;
|
||||
return !(*p_)[it - c_->begin()];
|
||||
}
|
||||
private:
|
||||
const container_type* c_;
|
||||
const vector<bool>* p_;
|
||||
};
|
||||
|
||||
template <typename iterator, typename is_empty>
|
||||
struct hollow_iterator_base
|
||||
: public std::iterator<std::forward_iterator_tag,
|
||||
typename container_type::value_type> {
|
||||
typedef presence_type presence;
|
||||
typedef container_type container;
|
||||
typedef iterator_type iterator;
|
||||
typedef hollow_iterator_base<container, presence, iterator>& self_reference;
|
||||
typename iterator::value_type> {
|
||||
public:
|
||||
typedef hollow_iterator_base<iterator, is_empty>& self_type;
|
||||
typedef self_type& self_reference;
|
||||
typedef typename iterator::reference reference;
|
||||
typedef typename iterator::pointer pointer;
|
||||
|
||||
hollow_iterator_base(container* c, presence* p, iterator it)
|
||||
: c_(c), p_(p), it_(it) { if (c_) find_present(); }
|
||||
self_reference operator++() {
|
||||
++it_; find_present();
|
||||
hollow_iterator_base() : it_(), empty_() { }
|
||||
hollow_iterator_base(iterator it, is_empty empty) : it_(it), empty_(empty) {
|
||||
advance();
|
||||
}
|
||||
hollow_iterator_base(const self_type& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; }
|
||||
template <typename const_iterator>
|
||||
hollow_iterator_base(const hollow_iterator_base<const_iterator, is_empty>& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; }
|
||||
|
||||
reference operator*() { return *it_; }
|
||||
pointer operator->() { return &(*it_); }
|
||||
self_reference operator++() { ++it_; advance(); return *this; }
|
||||
// self_type operator++() { auto tmp(*this); ++tmp; return tmp; }
|
||||
|
||||
// TODO find syntax to make this less permissible at compile time
|
||||
template <class T>
|
||||
bool operator==(const T& rhs) { return rhs.it_ == this->it_; }
|
||||
template <class T>
|
||||
bool operator!=(const T& rhs) { return rhs.it_ != this->it_; }
|
||||
template <typename const_iterator>
|
||||
bool operator==(const hollow_iterator_base<const_iterator, is_empty>& rhs) { return rhs.it_ == it_; }
|
||||
template <typename const_iterator>
|
||||
bool operator!=(const hollow_iterator_base<const_iterator, is_empty>& rhs) { return rhs.it_ != it_; }
|
||||
|
||||
public: // TODO find syntax to make this friend of const iterator
|
||||
void find_present() {
|
||||
while (it_ != c_->end() && !((*p_)[it_-c_->begin()])) ++it_;
|
||||
}
|
||||
container* c_;
|
||||
presence* p_;
|
||||
// should be friend
|
||||
iterator it_;
|
||||
is_empty empty_;
|
||||
|
||||
private:
|
||||
void advance() {
|
||||
while (empty_(it_)) ++it_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename container_type>
|
||||
struct hollow_iterator : public hollow_iterator_base<
|
||||
container_type, std::vector<bool>, typename container_type::iterator> {
|
||||
typedef hollow_iterator_base<
|
||||
container_type, std::vector<bool>, typename container_type::iterator> parent_class;
|
||||
hollow_iterator() : parent_class(NULL, NULL, typename container_type::iterator()) { }
|
||||
hollow_iterator(typename parent_class::container* c,
|
||||
typename parent_class::presence* p,
|
||||
typename parent_class::iterator it)
|
||||
: parent_class(c, p, it) { }
|
||||
};
|
||||
|
||||
template <typename container_type>
|
||||
struct hollow_const_iterator : public hollow_iterator_base<
|
||||
const container_type, const std::vector<bool>, typename container_type::const_iterator> {
|
||||
typedef hollow_iterator_base<
|
||||
const container_type, const std::vector<bool>, typename container_type::const_iterator> parent_class;
|
||||
typedef hollow_const_iterator<container_type> self_type;
|
||||
typedef hollow_iterator<container_type> non_const_type;
|
||||
hollow_const_iterator(non_const_type rhs) : parent_class(rhs.c_, rhs.p_, typename container_type::const_iterator(rhs.it_)) { }
|
||||
hollow_const_iterator() : parent_class(NULL, NULL, typename container_type::iterator()) { }
|
||||
hollow_const_iterator(const typename parent_class::container* c,
|
||||
const typename parent_class::presence* p,
|
||||
typename parent_class::iterator it)
|
||||
: parent_class(c, p, it) { }
|
||||
};
|
||||
template <typename container_type, typename iterator> auto make_hollow(
|
||||
container_type* v, vector<bool>* p, iterator it) ->
|
||||
hollow_iterator_base<iterator, is_empty<container_type>> {
|
||||
return hollow_iterator_base<iterator, is_empty<container_type>>(
|
||||
it, is_empty<container_type>(v, p));
|
||||
}
|
||||
|
||||
} // namespace cxxmph
|
||||
|
||||
|
@ -1,12 +1,16 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include "hollow_iterator.h"
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
using cxxmph::hollow_iterator;
|
||||
using cxxmph::hollow_const_iterator;
|
||||
#include "hollow_iterator.h"
|
||||
using cxxmph::hollow_iterator_base;
|
||||
using cxxmph::make_hollow;
|
||||
using cxxmph::is_empty;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
vector<int> v;
|
||||
@ -15,24 +19,27 @@ int main(int argc, char** argv) {
|
||||
v.push_back(i);
|
||||
p.push_back(i % 2 == 0);
|
||||
}
|
||||
auto begin = hollow_iterator<vector<int>>(&v, &p, v.begin());
|
||||
auto end = hollow_iterator<vector<int>>(&v, &p, v.end());
|
||||
auto begin = make_hollow(&v, &p, v.begin());
|
||||
auto end = make_hollow(&v, &p, v.end());
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
if (((*it) % 2) != 0) exit(-1);
|
||||
}
|
||||
hollow_const_iterator<vector<int>> const_begin(begin);
|
||||
hollow_const_iterator<vector<int>> const_end(end);
|
||||
for (auto it = const_begin; it != const_end; ++it) {
|
||||
const vector<int>* cv(&v);
|
||||
auto cbegin(make_hollow(cv, &p, cv->begin()));
|
||||
auto cend(make_hollow(cv, &p, cv->begin()));
|
||||
for (auto it = cbegin; it != cend; ++it) {
|
||||
if (((*it) % 2) != 0) exit(-1);
|
||||
}
|
||||
vector<int>::iterator vit1 = v.begin();
|
||||
vector<int>::const_iterator vit2 = v.begin();
|
||||
if (vit1 != vit2) exit(-1);
|
||||
auto it1 = hollow_iterator<vector<int>>(&v, &p, v.begin());
|
||||
auto it2 = hollow_const_iterator<vector<int>>(&v, &p, v.begin());
|
||||
auto it1 = make_hollow(&v, &p, vit1);
|
||||
auto it2 = make_hollow(&v, &p, vit2);
|
||||
if (it1 != it2) exit(-1);
|
||||
|
||||
hollow_iterator<vector<int>> default_constructed;
|
||||
default_constructed = hollow_iterator<vector<int>>(&v, &p, v.begin());
|
||||
typedef is_empty<vector<int>> iev;
|
||||
hollow_iterator_base<vector<int>::iterator, iev> default_constructed;
|
||||
default_constructed = make_hollow(&v, &p, v.begin());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
namespace cxxmph {
|
||||
|
||||
const uint8_t dynamic_2bitset::vmask[] = { 0xfc, 0xf3, 0xcf, 0x3f};
|
||||
dynamic_2bitset::dynamic_2bitset() : size_(0), fill_(false) {}
|
||||
dynamic_2bitset::dynamic_2bitset(uint32_t size, bool fill)
|
||||
: size_(size), fill_(fill), data_(ceil(size / 4.0), ones()*fill) {}
|
||||
dynamic_2bitset::~dynamic_2bitset() {}
|
||||
|
||||
template <int n, int mask = (1 << 7)> struct bitcount {
|
||||
enum { value = (n & mask ? 1:0) + bitcount<n, (mask >> 1)>::value };
|
||||
@ -23,6 +27,9 @@ static CompileTimeRankTable<256> kRanktable;
|
||||
|
||||
uint8_t Ranktable::get(uint8_t i) { return kRanktable[i]; }
|
||||
|
||||
|
||||
void stop_unused_warning() {
|
||||
rank64(4);
|
||||
nextpoweroftwo(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,10 +17,9 @@ namespace cxxmph {
|
||||
|
||||
class dynamic_2bitset {
|
||||
public:
|
||||
dynamic_2bitset() : size_(0), fill_(false) {}
|
||||
dynamic_2bitset(uint32_t size, bool fill = false)
|
||||
: size_(size), fill_(fill), data_(ceil(size / 4.0), ones()*fill) {
|
||||
}
|
||||
dynamic_2bitset();
|
||||
~dynamic_2bitset();
|
||||
dynamic_2bitset(uint32_t size, bool fill = false);
|
||||
|
||||
const uint8_t operator[](uint32_t i) const { return get(i); }
|
||||
const uint8_t get(uint32_t i) const {
|
||||
@ -28,7 +27,7 @@ class dynamic_2bitset {
|
||||
assert((i >> 2) < data_.size());
|
||||
return (data_[(i >> 2)] >> (((i & 3) << 1)) & 3);
|
||||
}
|
||||
uint8_t set(uint32_t i, uint8_t v) {
|
||||
void set(uint32_t i, uint8_t v) {
|
||||
assert((i >> 2) < data_.size());
|
||||
data_[(i >> 2)] |= ones() ^ dynamic_2bitset::vmask[i & 3];
|
||||
data_[(i >> 2)] &= ((v << ((i & 3) << 1)) | dynamic_2bitset::vmask[i & 3]);
|
||||
@ -59,7 +58,7 @@ class dynamic_2bitset {
|
||||
static uint32_t nextpoweroftwo(uint32_t k) {
|
||||
if (k == 0) return 1;
|
||||
k--;
|
||||
for (int i=1; i<sizeof(uint32_t)*CHAR_BIT; i<<=1) k = k | k >> i;
|
||||
for (uint32_t i=1; i<sizeof(uint32_t)*CHAR_BIT; i<<=1) k = k | k >> i;
|
||||
return k+1;
|
||||
}
|
||||
// Interesting bit tricks that might end up here:
|
||||
|
@ -5,34 +5,35 @@
|
||||
|
||||
using cxxmph::dynamic_2bitset;
|
||||
using cxxmph::rank64;
|
||||
using cxxmph::nextpoweroftwo;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
dynamic_2bitset small(256, true);
|
||||
for (int i = 0; i < small.size(); ++i) small.set(i, i % 4);
|
||||
for (int i = 0; i < small.size(); ++i) {
|
||||
for (uint32_t i = 0; i < small.size(); ++i) small.set(i, i % 4);
|
||||
for (uint32_t i = 0; i < small.size(); ++i) {
|
||||
if (small[i] != i % 4) {
|
||||
fprintf(stderr, "wrong bits %d at %d expected %d\n", small[i], i, i % 4);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int size = 256;
|
||||
uint32_t size = 256;
|
||||
dynamic_2bitset bits(size, true /* fill with ones */);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
if (bits[i] != 3) {
|
||||
fprintf(stderr, "wrong bits %d at %d expected %d\n", bits[i], i, 3);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; ++i) bits.set(i, 0);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (uint32_t i = 0; i < size; ++i) bits.set(i, 0);
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
if (bits[i] != 0) {
|
||||
fprintf(stderr, "wrong bits %d at %d expected %d\n", bits[i], i, 0);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; ++i) bits.set(i, i % 4);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (uint32_t i = 0; i < size; ++i) bits.set(i, i % 4);
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
if (bits[i] != i % 4) {
|
||||
fprintf(stderr, "wrong bits %d at %d expected %d\n", bits[i], i, i % 4);
|
||||
exit(-1);
|
||||
@ -44,7 +45,7 @@ int main(int argc, char** argv) {
|
||||
if (size_corner2.size() != 2) exit(-1);
|
||||
(dynamic_2bitset(4, true)).swap(size_corner2);
|
||||
if (size_corner2.size() != 4) exit(-1);
|
||||
for (int i = 0; i < size_corner2.size(); ++i) {
|
||||
for (uint32_t i = 0; i < size_corner2.size(); ++i) {
|
||||
if (size_corner2[i] != 3) exit(-1);
|
||||
}
|
||||
size_corner2.clear();
|
||||
@ -55,6 +56,8 @@ int main(int argc, char** argv) {
|
||||
dynamic_2bitset large(1000, true);
|
||||
empty.swap(large);
|
||||
|
||||
if (nextpoweroftwo(3) != 4) exit(-1);
|
||||
|
||||
if (rank64(0) != 0) exit(-1);
|
||||
if (rank64(1) != 1) exit(-1);
|
||||
if (rank64(2) != 1) exit(-1);
|
||||
|
@ -128,7 +128,7 @@ bool MPHIndex::Reset(
|
||||
nest_displacement_[0] = 0;
|
||||
nest_displacement_[1] = r_;
|
||||
nest_displacement_[2] = (r_ << 1);
|
||||
for (int i = 0; i < sizeof(threebit_mod3); ++i) threebit_mod3[i] = i % 3;
|
||||
for (uint32_t i = 0; i < sizeof(threebit_mod3); ++i) threebit_mod3[i] = i % 3;
|
||||
|
||||
n_ = 3*r_;
|
||||
k_ = 1U << b_;
|
||||
|
@ -35,6 +35,7 @@ using std::vector;
|
||||
#define MPH_MAP_TMPL_SPEC template <class Key, class Data, class HashFcn, class EqualKey, class Alloc>
|
||||
#define MPH_MAP_CLASS_SPEC mph_map<Key, Data, HashFcn, EqualKey, Alloc>
|
||||
#define MPH_MAP_METHOD_DECL(r, m) MPH_MAP_TMPL_SPEC typename MPH_MAP_CLASS_SPEC::r MPH_MAP_CLASS_SPEC::m
|
||||
#define MPH_MAP_INLINE_METHOD_DECL(r, m) MPH_MAP_TMPL_SPEC inline typename MPH_MAP_CLASS_SPEC::r MPH_MAP_CLASS_SPEC::m
|
||||
|
||||
template <class Key, class Data, class HashFcn = std::hash<Key>, class EqualKey = std::equal_to<Key>, class Alloc = std::allocator<Data> >
|
||||
class mph_map {
|
||||
@ -72,10 +73,10 @@ class mph_map {
|
||||
void erase(iterator pos);
|
||||
void erase(const key_type& k);
|
||||
pair<iterator, bool> insert(const value_type& x);
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
inline iterator find(const key_type& k);
|
||||
inline const_iterator find(const key_type& k) const;
|
||||
typedef int32_t my_int32_t; // help macros
|
||||
int32_t index(const key_type& k) const;
|
||||
inline int32_t index(const key_type& k) const;
|
||||
data_type& operator[](const key_type &k);
|
||||
const data_type& operator[](const key_type &k) const;
|
||||
|
||||
@ -149,7 +150,7 @@ MPH_MAP_METHOD_DECL(void_type, pack)() {
|
||||
bool success = index_.Reset(
|
||||
make_iterator_first(begin()),
|
||||
make_iterator_first(end()), size_);
|
||||
assert(success);
|
||||
if (!success) { exit(-1); }
|
||||
std::vector<value_type> new_values(index_.minimal_perfect_hash_size());
|
||||
new_values.reserve(new_values.size() * 2);
|
||||
std::vector<bool> new_present(index_.minimal_perfect_hash_size(), false);
|
||||
@ -193,21 +194,21 @@ MPH_MAP_METHOD_DECL(void_type, erase)(const key_type& k) {
|
||||
erase(it);
|
||||
}
|
||||
|
||||
MPH_MAP_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 it = begin() + idx;
|
||||
if (idx == -1 || it->first != k) return end();
|
||||
return it;
|
||||
}
|
||||
|
||||
MPH_MAP_METHOD_DECL(iterator, find)(const key_type& k) {
|
||||
MPH_MAP_INLINE_METHOD_DECL(iterator, find)(const key_type& k) {
|
||||
auto idx = index(k);
|
||||
auto it = begin() + idx;
|
||||
if (idx == -1 || it->first != k) return end();
|
||||
return it;
|
||||
}
|
||||
|
||||
MPH_MAP_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 {
|
||||
if (__builtin_expect(!slack_.empty(), 0)) {
|
||||
auto sit = slack_.find(hasher128_.hash128(k, 0));
|
||||
if (sit != slack_.end()) return sit->second;
|
||||
|
@ -88,6 +88,7 @@ struct Murmur3Fmix64bitsType {
|
||||
h128 h;
|
||||
h.set64(fmix(k), 0);
|
||||
h.set64(fmix(h.get64(0)), 1);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ int main(int argc, char** argv) {
|
||||
for (int i = 0; i < 1000; ++i) if (g[i] != i) exit(-1);
|
||||
|
||||
auto inthasher = seeded_hash_function<std::hash<uint64_t>>();
|
||||
unordered_map<h128, int, h128::hash32> g2;
|
||||
unordered_map<h128, uint64_t, h128::hash32> g2;
|
||||
for (uint64_t i = 0; i < 1000; ++i) {
|
||||
auto h = inthasher.hash128(i, 0);
|
||||
if (g2.find(h) != g2.end()) {
|
||||
|
@ -20,6 +20,7 @@ TriGraph::TriGraph(uint32_t nvertices, uint32_t nedges)
|
||||
next_edge_(nedges),
|
||||
first_edge_(nvertices, kInvalidEdge),
|
||||
vertex_degree_(nvertices, 0) { }
|
||||
TriGraph::~TriGraph() {}
|
||||
|
||||
void TriGraph::ExtractEdgesAndClear(vector<Edge>* edges) {
|
||||
vector<Edge>().swap(next_edge_);
|
||||
@ -67,7 +68,7 @@ void TriGraph::RemoveEdge(uint32_t current_edge) {
|
||||
}
|
||||
|
||||
void TriGraph::DebugGraph() const {
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < edges_.size(); i++){
|
||||
cerr << i << " " << edges_[i][0] << " " << edges_[i][1] << " " << edges_[i][2]
|
||||
<< " nexts " << next_edge_[i][0] << " " << next_edge_[i][1] << " " << next_edge_[i][2] << endl;
|
||||
|
@ -26,6 +26,7 @@ class TriGraph {
|
||||
uint32_t vertices[3];
|
||||
};
|
||||
TriGraph(uint32_t nedges, uint32_t nvertices);
|
||||
~TriGraph();
|
||||
void AddEdge(const Edge& edge);
|
||||
void RemoveEdge(uint32_t edge_id);
|
||||
void ExtractEdgesAndClear(std::vector<Edge>* edges);
|
||||
|
Loading…
Reference in New Issue
Block a user