From 24024006a94766b239b2f9ce8929745a8d5bced8 Mon Sep 17 00:00:00 2001 From: Christoph Schwering Date: Mon, 31 Jul 2017 08:39:23 +1000 Subject: [PATCH] Removed unused internal::HashSet. --- src/limbo/internal/hashset.h | 363 ----------------------------------- tests/CMakeLists.txt | 2 +- tests/hashset.cc | 71 ------- 3 files changed, 1 insertion(+), 435 deletions(-) delete mode 100644 src/limbo/internal/hashset.h delete mode 100644 tests/hashset.cc diff --git a/src/limbo/internal/hashset.h b/src/limbo/internal/hashset.h deleted file mode 100644 index 5deaafb..0000000 --- a/src/limbo/internal/hashset.h +++ /dev/null @@ -1,363 +0,0 @@ -// vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab -// Copyright 2017 Christoph Schwering -// Licensed under the MIT license. See LICENSE file in the project root. -// -// A closed hash set. - -#ifndef LIMBO_INTERNAL_HASHSET_H_ -#define LIMBO_INTERNAL_HASHSET_H_ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace limbo { -namespace internal { - -template, typename Equal = std::equal_to> -class HashSet { - public: - typedef typename std::result_of::type hash_t; - - struct Cell { - Cell() = default; - Cell(const Cell&) = default; - Cell& operator=(const Cell&) = default; - Cell(Cell&&) = default; - Cell& operator=(Cell&&) = default; - Cell(const T& val, hash_t hash) : val(val), hash(hash) {} - Cell(T&& val, hash_t hash) : val(std::forward(val)), hash(hash) {} - - static hash_t mask(const hash_t h) { return h & ~(kRemoved | kFresh); } - - void MarkRemoved() { hash = kRemoved; } - - bool occupied() const { return (hash & (kRemoved | kFresh)) == 0; } - bool removed() const { return (hash & kRemoved) != 0; } - bool fresh() const { return (hash & kFresh) != 0; } - - T val; - hash_t hash = kFresh; - - private: - static constexpr hash_t kRemoved = static_cast(1) << (sizeof(hash_t) * 8 - 2); - static constexpr hash_t kFresh = static_cast(1) << (sizeof(hash_t) * 8 - 1); - }; - - template - class Iterator { - public: - typedef std::ptrdiff_t difference_type; - typedef U value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::forward_iterator_tag iterator_category; - typedef iterator_proxy proxy; - - Iterator() = default; - explicit Iterator(InputIt end) : now_(end) { } - Iterator(InputIt now, InputIt end) : now_(now), end_(end) { Next(); } - - bool operator==(Iterator it) const { return now_ == it.now_; } - bool operator!=(Iterator it) const { return !(*this == it); } - - reference operator*() const { return now_->val; } - Iterator& operator++() { - ++now_; - Next(); - return *this; - } - - pointer operator->() const { return &now_->val; } - proxy operator++(int) { proxy p(operator*()); operator++(); return p; } - - Cell* cell() const { return const_cast(now_.operator->()); } - - private: - void Next() { - while (now_ != end_ && !now_->occupied()) { - ++now_; - } - } - - InputIt now_; - InputIt end_; - }; - - template - class BucketIterator { - public: - typedef std::ptrdiff_t difference_type; - typedef U value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::forward_iterator_tag iterator_category; - typedef iterator_proxy proxy; - - BucketIterator() = default; - explicit BucketIterator(InputIt end) : now_(end) {} - BucketIterator(hash_t h, InputIt now, InputIt begin, InputIt end) : - hash_(h), now_(now), now_bak_(now), begin_(begin), end_(end) { Next(true); } - - bool operator==(BucketIterator it) const { return now_ == it.now_; } - bool operator!=(BucketIterator it) const { return !(*this == it); } - - reference operator*() const { return now_->val; } - BucketIterator& operator++() { - ++now_; - Next(); - return *this; - } - - pointer operator->() const { return &now_->val; } - proxy operator++(int) { proxy p(operator*()); operator++(); return p; } - - Cell* cell() const { return const_cast(now_.operator->()); } - - private: - void Next(bool first = false) { - while ((first || now_ != now_bak_) && !cell()->fresh() && (cell()->removed() || cell()->hash != hash_)) { - if (now_ == end_) { - now_ = begin_; - } else { - ++now_; - } - first = false; - } - if ((!first && now_ == now_bak_) || cell()->fresh()) { - now_ = end_; - } - } - - hash_t hash_; - InputIt now_; - InputIt now_bak_; - InputIt begin_; - InputIt end_; - }; - - typedef Iterator::iterator> iterator; - typedef Iterator::const_iterator> const_iterator; - - typedef BucketIterator::iterator> bucket_iterator; - typedef BucketIterator::const_iterator> const_bucket_iterator; - - explicit HashSet(size_t capacity = 0, Hash hash = Hash(), Equal equal = Equal()) : - hash_(hash), - equal_(equal), - vec_(Capacity(capacity)) {} - - template - HashSet(ForwardIt begin, ForwardIt end, Hash hash = Hash(), Equal equal = Equal()) : - HashSet(std::distance(begin, end), hash, equal) { - for (; begin != end; ++begin) { - Add(*begin); - } - } - - template - HashSet(std::initializer_list xs, Hash hash = Hash(), Equal equal = Equal()) : - HashSet(xs.size(), hash, equal) { - for (auto& x : xs) { - Add(x); - } - } - - HashSet(const HashSet&) = default; - HashSet& operator=(const HashSet& s) = default; - - HashSet(HashSet&&) = default; - HashSet& operator=(HashSet&& s) = default; - - iterator begin() { return iterator(vec_.begin(), vec_.end()); } - iterator end() { return iterator(vec_.end()); } - - const_iterator begin() const { return const_iterator(vec_.begin(), vec_.end()); } - const_iterator end() const { return const_iterator(vec_.end()); } - - bucket_iterator bucket_begin(const T& val) { return bucket_begin(hash(val)); } - bucket_iterator bucket_begin(hash_t h) { - h = Cell::mask(h); - return bucket_iterator(h, vec_.begin() + (h % capacity()), vec_.begin(), vec_.end()); - } - bucket_iterator bucket_end() { return bucket_iterator(vec_.end()); } - - const_bucket_iterator bucket_begin(const T& val) const { return bucket_begin(hash(val)); } - const_bucket_iterator bucket_begin(hash_t h) const { - h = Cell::mask(h); - return const_bucket_iterator(h, vec_.begin() + (h % capacity()), vec_.begin(), vec_.end()); - } - const_bucket_iterator bucket_end() const { return const_bucket_iterator(vec_.end()); } - - size_t capacity() const { return vec_.size(); } - size_t size() const { return size_; } - bool empty() const { return size_ == 0; } - - bool Add(const T& val) { - Rehash(size_ + 1); - const hash_t h = hash(val); - hash_t i = h % capacity(); - size_t c = capacity(); - while (!vec_[i].fresh() && c-- > 0) { - if (vec_[i].occupied() && h == vec_[i].hash && equal_(vec_[i].val, val)) { - return false; - } - ++i; - i %= capacity(); - } - vec_[i] = Cell(val, h); - ++size_; - return true; - } - - bool Remove(const T& val) { - const hash_t h = hash(val); - hash_t i = h % capacity(); - size_t c = capacity(); - while (!vec_[i].fresh() && c-- > 0) { - if (vec_[i].occupied() && h == vec_[i].hash && equal_(vec_[i].val, val)) { - vec_[i].MarkRemoved(); - --size_; - return true; - } - ++i; - i %= capacity(); - } - return false; - } - - void Remove(iterator it) { it.cell()->MarkRemoved(); --size_; } - void Remove(const_iterator it) { it.cell()->MarkRemoved(); --size_; } - void Remove(bucket_iterator it) { it.cell()->MarkRemoved(); --size_; } - void Remove(const_bucket_iterator it) { it.cell()->MarkRemoved(); --size_; } - - bool RemoveHash(hash_t h) { - h = Cell::mask(h); - hash_t i = h % capacity(); - size_t c = capacity(); - while (!vec_[i].fresh() && c-- > 0) { - if (vec_[i].occupied() && h == vec_[i].hash) { - vec_[i].MarkRemoved(); - --size_; - return true; - } - ++i; - i %= capacity(); - } - return false; - } - - void RemoveAllHashes(hash_t h) { - h = Cell::mask(h); - hash_t i = h % capacity(); - size_t c = capacity(); - while (!vec_[i].fresh() && c-- > 0) { - if (vec_[i].occupied() && h == vec_[i].hash) { - vec_[i].MarkRemoved(); - --size_; - } - ++i; - i %= capacity(); - } - } - - void Clear() { - for (size_t i = 0; i < vec_.size(); ++i) { - vec_[i] = Cell(); - } - } - - bool Contains(const T& val) const { - const hash_t h = hash(val); - hash_t i = h % capacity(); - hash_t p = i; - size_t c = capacity(); - while (!vec_[i].fresh() && c-- > 0) { - if (vec_[i].occupied()) { - if (h == vec_[i].hash && equal_(val, vec_[i].val)) { - if (p != i) { - std::swap(vec_[p], vec_[i]); - } - return true; - } - } else { - p = i; - } - ++i; - i %= capacity(); - } - return false; - } - - bool ContainsHash(hash_t h) const { - h = Cell::mask(h); - hash_t i = h % capacity(); - hash_t p = i; - size_t c = capacity(); - while (!vec_[i].fresh() && c-- > 0) { - if (vec_[i].occupied()) { - if (h == vec_[i].hash) { - if (p != i) { - assert(vec_[p].removed()); - std::swap(vec_[p], vec_[i]); - } - return true; - } - } else { - p = i; - } - ++i; - i %= capacity(); - } - return false; - } - - private: - hash_t hash(const T& val) const { return Cell::mask(hash_(val)); } - - static size_t Capacity(size_t cap) { - static const size_t primes[] = { 3, 7, 11, 23, 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, - 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, - 345550609, 691101253 }; - static const size_t n_primes = sizeof(primes) / sizeof(primes[0]); - for (size_t i = 1; i < n_primes; ++i) { - if (cap + cap / 2 <= primes[i]) { - return primes[i]; - } - } - return primes[n_primes - 1]; - } - - void Rehash(size_t cap) { - cap = Capacity(cap); - if (cap > capacity()) { - std::vector old(cap); - std::swap(vec_, old); - for (size_t i = 0; i < old.size(); ++i) { - if (old[i].occupied()) { - Add(std::forward(old[i].val)); - } - } - } - } - - Hash hash_; - Equal equal_; - size_t size_ = 0; - mutable std::vector vec_; -}; - -} // namespace internal -} // namespace limbo - -#endif // LIMBO_INTERNAL_HASHSET_H_ - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8c154c9..cf5ad01 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory (googletest) enable_testing () include_directories (${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) -foreach (test hash iter hashset intmap term bloom literal clause setup formula syntax grounder solver kb) +foreach (test hash iter intmap term bloom literal clause setup formula syntax grounder solver kb) add_executable (${test} ${test}.cc) target_link_libraries (${test} LINK_PUBLIC limbo gtest gtest_main) add_test (NAME ${test} COMMAND ${test}) diff --git a/tests/hashset.cc b/tests/hashset.cc deleted file mode 100644 index cc5b828..0000000 --- a/tests/hashset.cc +++ /dev/null @@ -1,71 +0,0 @@ -// vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab -// Copyright 2016 Christoph Schwering - -#include - -#include - -#include - -#include - -struct Value { - Value() = default; - Value(int x) : x(x) {} - bool operator==(const Value i) const { return x == i.x; } - bool operator!=(const Value i) const { return x != i.x; } - int x; -}; - -std::ostream& operator<<(std::ostream& os, Value i) { return std::cout << i.x; } - -using namespace limbo::format; - -namespace limbo { -namespace internal { - -TEST(HashSetTest, main) { - struct Hash { internal::hash32_t operator()(Value i) const { return i.x/2; } }; - struct Equal { bool operator()(Value i, Value j) const { return i.x == j.x; } }; - typedef HashSet HS; - HS hs(10); - for (int x = 0; x < 10; ++x) { - bool r = hs.Add(x); - EXPECT_TRUE(r); - EXPECT_TRUE(hs.Contains(x)); - EXPECT_TRUE(hs.ContainsHash(Hash()(x))); - } - EXPECT_EQ(hs.size(), 10); - EXPECT_EQ(hs.size(), std::distance(hs.begin(), hs.end())); - EXPECT_GE(hs.capacity(), 10); - for (int x = 0; x < 10; ++x) { - for (auto it = hs.bucket_begin(Value(x)), jt = hs.bucket_end(); it != jt; ++it) { - EXPECT_TRUE(it->x == x-1 || it->x == x || it->x == x+1); - } - EXPECT_EQ(std::distance(hs.bucket_begin(Value(x)), hs.bucket_end()), 2); - } - for (int x = 0; x < 10; ++x) { - bool r = hs.Add(x); - EXPECT_FALSE(r); - } - EXPECT_EQ(hs.size(), 10); - EXPECT_EQ(hs.size(), std::distance(hs.begin(), hs.end())); - for (int x = 0; x < 10; ++x) { - if (x % 2 == 0) { - hs.Remove(x); - EXPECT_FALSE(hs.Contains(x)); - EXPECT_TRUE(hs.ContainsHash(Hash()(x))); - } - } - EXPECT_EQ(hs.size(), 5); - EXPECT_EQ(hs.size(), std::distance(hs.begin(), hs.end())); - { - std::vector xs = std::vector(hs.begin(), hs.end()); - std::vector ys = {Value(1),Value(3),Value(5),Value(7),Value(9)}; - EXPECT_EQ(xs, ys); - } -} - -} // namespace internal -} // namespace limbo - -- GitLab