diff --git a/configure.ac b/configure.ac index 172b02f..fcb829b 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/cxxmph/Makefile.am b/cxxmph/Makefile.am index f99a284..9a2e08b 100644 --- a/cxxmph/Makefile.am +++ b/cxxmph/Makefile.am @@ -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 diff --git a/cxxmph/benchmark.cc b/cxxmph/benchmark.cc index 70175e1..1f260fa 100644 --- a/cxxmph/benchmark.cc +++ b/cxxmph/benchmark.cc @@ -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 bm(g_benchmarks[i]); if (!bm->SetUp()) { cerr << "Set up phase for benchmark " diff --git a/cxxmph/bm_common.cc b/cxxmph/bm_common.cc index 7e94dcf..1baaa09 100644 --- a/cxxmph/bm_common.cc +++ b/cxxmph/bm_common.cc @@ -14,6 +14,7 @@ using std::vector; namespace cxxmph { +UrlsBenchmark::~UrlsBenchmark() {} bool UrlsBenchmark::SetUp() { vector 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::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 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]; } diff --git a/cxxmph/bm_common.h b/cxxmph/bm_common.h index 8412f98..178ee36 100644 --- a/cxxmph/bm_common.h +++ b/cxxmph/bm_common.h @@ -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(); diff --git a/cxxmph/bm_index.cc b/cxxmph/bm_index.cc index 9345a11..d1cbc00 100644 --- a/cxxmph/bm_index.cc +++ b/cxxmph/bm_index.cc @@ -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: diff --git a/cxxmph/bm_map.cc b/cxxmph/bm_map.cc index d5d34a8..039b5d6 100644 --- a/cxxmph/bm_map.cc +++ b/cxxmph/bm_map.cc @@ -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); } } diff --git a/cxxmph/cxxmph.cc b/cxxmph/cxxmph.cc index e9bffd0..b544acd 100644 --- a/cxxmph/cxxmph.cc +++ b/cxxmph/cxxmph.cc @@ -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 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::const_iterator it = table.begin(); mph_map::const_iterator end = table.end(); for (int i = 0; it != end; ++it, ++i) { diff --git a/cxxmph/hollow_iterator.h b/cxxmph/hollow_iterator.h index c650d21..ae102e0 100644 --- a/cxxmph/hollow_iterator.h +++ b/cxxmph/hollow_iterator.h @@ -5,66 +5,65 @@ namespace cxxmph { -template +using std::vector; + +template +struct is_empty { + public: + is_empty() : c_(NULL), p_(NULL) {}; + is_empty(const container_type* c, const vector* 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* p_; +}; + +template struct hollow_iterator_base : public std::iterator { - typedef presence_type presence; - typedef container_type container; - typedef iterator_type iterator; - typedef hollow_iterator_base& self_reference; + typename iterator::value_type> { + public: + typedef hollow_iterator_base& self_type; + typedef self_type& self_reference; typedef typename iterator::reference reference; typedef typename iterator::pointer pointer; + 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 + hollow_iterator_base(const hollow_iterator_base& rhs) { it_ = rhs.it_; empty_ = rhs.empty_; } - 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(); - } 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 - bool operator==(const T& rhs) { return rhs.it_ == this->it_; } - template - bool operator!=(const T& rhs) { return rhs.it_ != this->it_; } + template + bool operator==(const hollow_iterator_base& rhs) { return rhs.it_ == it_; } + template + bool operator!=(const hollow_iterator_base& 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 -struct hollow_iterator : public hollow_iterator_base< - container_type, std::vector, typename container_type::iterator> { - typedef hollow_iterator_base< - container_type, std::vector, 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 -struct hollow_const_iterator : public hollow_iterator_base< - const container_type, const std::vector, typename container_type::const_iterator> { - typedef hollow_iterator_base< - const container_type, const std::vector, typename container_type::const_iterator> parent_class; - typedef hollow_const_iterator self_type; - typedef hollow_iterator 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 auto make_hollow( + container_type* v, vector* p, iterator it) -> + hollow_iterator_base> { + return hollow_iterator_base>( + it, is_empty(v, p)); +} } // namespace cxxmph diff --git a/cxxmph/hollow_iterator_test.cc b/cxxmph/hollow_iterator_test.cc index 07963ae..c507eef 100644 --- a/cxxmph/hollow_iterator_test.cc +++ b/cxxmph/hollow_iterator_test.cc @@ -1,12 +1,16 @@ #include #include #include +#include -#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 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>(&v, &p, v.begin()); - auto end = hollow_iterator>(&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> const_begin(begin); - hollow_const_iterator> const_end(end); - for (auto it = const_begin; it != const_end; ++it) { + const vector* 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::iterator vit1 = v.begin(); vector::const_iterator vit2 = v.begin(); if (vit1 != vit2) exit(-1); - auto it1 = hollow_iterator>(&v, &p, v.begin()); - auto it2 = hollow_const_iterator>(&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> default_constructed; - default_constructed = hollow_iterator>(&v, &p, v.begin()); + typedef is_empty> iev; + hollow_iterator_base::iterator, iev> default_constructed; + default_constructed = make_hollow(&v, &p, v.begin()); + return 0; } diff --git a/cxxmph/mph_bits.cc b/cxxmph/mph_bits.cc index 8c4185e..423700a 100644 --- a/cxxmph/mph_bits.cc +++ b/cxxmph/mph_bits.cc @@ -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 struct bitcount { enum { value = (n & mask ? 1:0) + bitcount> 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); +} } diff --git a/cxxmph/mph_bits.h b/cxxmph/mph_bits.h index 57debec..74a97bb 100644 --- a/cxxmph/mph_bits.h +++ b/cxxmph/mph_bits.h @@ -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> i; + for (uint32_t i=1; i> i; return k+1; } // Interesting bit tricks that might end up here: diff --git a/cxxmph/mph_bits_test.cc b/cxxmph/mph_bits_test.cc index 7af4b66..42170ff 100644 --- a/cxxmph/mph_bits_test.cc +++ b/cxxmph/mph_bits_test.cc @@ -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(); @@ -54,6 +55,8 @@ int main(int argc, char** argv) { empty.clear(); 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); diff --git a/cxxmph/mph_index.h b/cxxmph/mph_index.h index 35ca9d7..1f6ace1 100644 --- a/cxxmph/mph_index.h +++ b/cxxmph/mph_index.h @@ -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_; diff --git a/cxxmph/mph_map.h b/cxxmph/mph_map.h index 7b3160d..1d58e32 100644 --- a/cxxmph/mph_map.h +++ b/cxxmph/mph_map.h @@ -35,6 +35,7 @@ using std::vector; #define MPH_MAP_TMPL_SPEC template #define MPH_MAP_CLASS_SPEC mph_map #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 EqualKey = std::equal_to, class Alloc = std::allocator > class mph_map { @@ -72,10 +73,10 @@ class mph_map { void erase(iterator pos); void erase(const key_type& k); pair 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 new_values(index_.minimal_perfect_hash_size()); new_values.reserve(new_values.size() * 2); std::vector 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; diff --git a/cxxmph/seeded_hash.h b/cxxmph/seeded_hash.h index 7332be4..e5e078d 100644 --- a/cxxmph/seeded_hash.h +++ b/cxxmph/seeded_hash.h @@ -88,6 +88,7 @@ struct Murmur3Fmix64bitsType { h128 h; h.set64(fmix(k), 0); h.set64(fmix(h.get64(0)), 1); + return h; } }; diff --git a/cxxmph/seeded_hash_test.cc b/cxxmph/seeded_hash_test.cc index e2983b0..e5f1268 100644 --- a/cxxmph/seeded_hash_test.cc +++ b/cxxmph/seeded_hash_test.cc @@ -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>(); - unordered_map g2; + unordered_map g2; for (uint64_t i = 0; i < 1000; ++i) { auto h = inthasher.hash128(i, 0); if (g2.find(h) != g2.end()) { diff --git a/cxxmph/trigraph.cc b/cxxmph/trigraph.cc index 5e9fd66..7e8fc8d 100644 --- a/cxxmph/trigraph.cc +++ b/cxxmph/trigraph.cc @@ -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* edges) { vector().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; diff --git a/cxxmph/trigraph.h b/cxxmph/trigraph.h index 22adaeb..045d427 100644 --- a/cxxmph/trigraph.h +++ b/cxxmph/trigraph.h @@ -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* edges);