Skip to content

Commit ea4de45

Browse files
ImmanuelHaffneralir3zakh
authored andcommitted
[Util] Merge both ADT.hpp headers into include.
We still had two `ADT.hpp` files back from the days when mu*t*able was closed source. We can now safely merge those two files into a single `include/mutable/util/ADT.hpp`.
1 parent ea0dcea commit ea4de45

File tree

9 files changed

+139
-149
lines changed

9 files changed

+139
-149
lines changed

include/mutable/util/ADT.hpp

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#pragma once
22

3-
#include <mutable/util/exception.hpp>
4-
#include <mutable/util/fn.hpp>
5-
#include <mutable/util/macro.hpp>
6-
#include <mutable/util/malloc_allocator.hpp>
73
#include <algorithm>
84
#include <climits>
95
#include <cstdint>
106
#include <iostream>
117
#include <limits>
128
#include <memory>
9+
#include <mutable/util/exception.hpp>
10+
#include <mutable/util/fn.hpp>
11+
#include <mutable/util/macro.hpp>
12+
#include <mutable/util/malloc_allocator.hpp>
1313
#include <sstream>
1414
#include <string>
1515
#include <type_traits>
@@ -750,4 +750,132 @@ view(range<It>, Fn&&) -> view<It, std::invoke_result_t<Fn&&, It>(It)>;
750750
template<typename It, typename Fn>
751751
view(It, It, Fn&&) -> view<It, std::invoke_result_t<Fn&&, It>(It)>;
752752

753+
/** A sorted list of elements. Allows duplicates. */
754+
template<typename T, typename Compare = std::less<T>>
755+
struct sorted_vector
756+
{
757+
using vector_type = std::vector<T>; ///< the type of the internal container of elements
758+
using value_type = T;
759+
using size_type = typename vector_type::size_type;
760+
761+
private:
762+
Compare comp_;
763+
vector_type v_; ///< the internal container of elements
764+
765+
public:
766+
sorted_vector(Compare comp = Compare()) : comp_(comp) { }
767+
768+
auto begin() { return v_.begin(); }
769+
auto end() { return v_.end(); }
770+
auto begin() const { return v_.begin(); }
771+
auto end() const { return v_.end(); }
772+
auto cbegin() const { return v_.cbegin(); }
773+
auto cend() const { return v_.cend(); }
774+
775+
/** Returns `true` iff the `sorted_vector` has no elements. */
776+
auto empty() const { return v_.empty(); }
777+
/** Returns the number of elements in this `sorted_vector`. */
778+
auto size() const { return v_.size(); }
779+
/** Reserves space for `new_cap` elements in this `sorted_vector`. */
780+
auto reserve(size_type new_cap) { return v_.reserve(new_cap); }
781+
782+
/** Returns `true` iff this `sorted_vector` contains an element that is equal to `value`. */
783+
bool contains(const T &value) const {
784+
auto pos = std::lower_bound(begin(), end(), value, comp_);
785+
return pos != end() and *pos == value;
786+
}
787+
788+
/** Inserts `value` into this `sorted_vector`. Returns an `iterator` pointing to the inserted element. */
789+
auto insert(T value) { return v_.insert(std::lower_bound(begin(), end(), value), value, comp_); }
790+
791+
/** Inserts elements in the range from `first` (including) to `last` (excluding) into this `sorted_vector. */
792+
template<typename InsertIt>
793+
void insert(InsertIt first, InsertIt last) {
794+
while (first != last)
795+
insert(*first++);
796+
}
797+
};
798+
799+
/** Enumerate all subsets of size `k` based on superset of size `n`.
800+
* See http://programmingforinsomniacs.blogspot.com/2018/03/gospers-hack-explained.html. */
801+
struct GospersHack
802+
{
803+
private:
804+
SmallBitset set_;
805+
uint64_t limit_;
806+
807+
GospersHack() { }
808+
809+
public:
810+
/** Create an instance of `GospersHack` that enumerates all subsets of size `k` of a set of `n` elements. */
811+
static GospersHack enumerate_all(uint64_t k, uint64_t n) {
812+
M_insist(k <= n, "invalid enumeration");
813+
M_insist(n < 64, "n exceeds range");
814+
GospersHack GH;
815+
GH.set_ = SmallBitset((1UL << k) - 1);
816+
GH.limit_ = 1UL << n;
817+
return GH;
818+
}
819+
/** Create an instance of `GospersHack` that enumerates all remaining subsets of a set of `n` elements, starting at
820+
* subset `set`. */
821+
static GospersHack enumerate_from(SmallBitset set, uint64_t n) {
822+
M_insist(n < 64, "n exceeds range");
823+
GospersHack GH;
824+
GH.set_ = set;
825+
GH.limit_ = 1UL << n;
826+
M_insist(uint64_t(set) <= GH.limit_, "set exceeds the limit");
827+
return GH;
828+
}
829+
830+
/** Advance to the next subset. */
831+
GospersHack & operator++() {
832+
const uint64_t s(set_);
833+
#ifdef __BMI__
834+
const uint64_t c = _blsi_u64(s); // BMI1: extract lowest set isolated bit -> c is a power of 2
835+
#else
836+
const uint64_t c = s & -s; // extract lowest set isolated bit -> c is a power of 2
837+
#endif
838+
const uint64_t r = s + c; // flip lowest block of 1-bits and following 0-bit
839+
const uint64_t m = r ^ s; // mask flipped bits, i.e. lowest block of 1-bits and following 0-bit
840+
#ifdef __BMI2__
841+
const uint64_t l = _pext_u64(m, m); // BMI2: deposit all set bits in the low bits
842+
#else
843+
const uint64_t l = (1UL << __builtin_popcount(m)) - 1UL; // deposit all set bits in the low bits
844+
#endif
845+
set_ = SmallBitset((l >> 2U) | r); // instead of divide by c, rshift by log2(c)
846+
return *this;
847+
}
848+
849+
/** Returns `false` iff all subsets have been enumerated. */
850+
operator bool() const { return uint64_t(set_) < limit_; }
851+
852+
/** Returns the current subset. */
853+
SmallBitset operator*() const { return SmallBitset(set_); }
854+
};
855+
856+
/** This class efficiently enumerates all subsets of a given size. */
857+
struct SubsetEnumerator
858+
{
859+
private:
860+
///> the set to compute the power set of
861+
SmallBitset set_;
862+
///> used to enumerate the power set of numbers 0 to n-1
863+
GospersHack GH_;
864+
865+
public:
866+
SubsetEnumerator(SmallBitset set, uint64_t size)
867+
: set_(set)
868+
, GH_(GospersHack::enumerate_all(size, set.size()))
869+
{
870+
M_insist(size <= set.size());
871+
}
872+
873+
SubsetEnumerator & operator++() { ++GH_; return *this; }
874+
operator bool() const { return bool(GH_); }
875+
SmallBitset operator*() const {
876+
auto gh_set = *GH_;
877+
return SmallBitset(_pdep_u64(uint64_t(gh_set), uint64_t(set_)));
878+
}
879+
};
880+
753881
}

src/IR/HeuristicSearchPlanEnumerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <mutable/IR/PlanEnumerator.hpp>
22

3-
#include "util/ADT.hpp"
43
#include <algorithm>
54
#include <boost/container/allocator.hpp>
65
#include <boost/container/node_allocator.hpp>
@@ -18,6 +17,7 @@
1817
#include <mutable/IR/PlanTable.hpp>
1918
#include <mutable/IR/QueryGraph.hpp>
2019
#include <mutable/Options.hpp>
20+
#include <mutable/util/ADT.hpp>
2121
#include <mutable/util/crtp.hpp>
2222
#include <mutable/util/fn.hpp>
2323
#include <mutable/util/HeuristicSearch.hpp>

src/IR/PlanEnumerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <mutable/IR/PlanEnumerator.hpp>
22

3-
#include "util/ADT.hpp"
43
#include <algorithm>
54
#include <cstring>
65
#include <execution>
@@ -10,6 +9,7 @@
109
#include <memory>
1110
#include <mutable/catalog/Catalog.hpp>
1211
#include <mutable/catalog/CostFunction.hpp>
12+
#include <mutable/util/ADT.hpp>
1313
#include <mutable/util/fn.hpp>
1414
#include <mutable/util/list_allocator.hpp>
1515
#include <mutable/util/malloc_allocator.hpp>

src/util/ADT.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "util/ADT.hpp"
1+
#include <mutable/util/ADT.hpp>
22

33

44
using namespace m;

src/util/ADT.hpp

Lines changed: 0 additions & 138 deletions
This file was deleted.

unittest/IR/PlanEnumeratorTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
#include <mutable/IR/PlanTable.hpp>
1010
#include <mutable/mutable.hpp>
1111
#include <mutable/storage/Store.hpp>
12+
#include <mutable/util/ADT.hpp>
1213
#include <parse/Parser.hpp>
1314
#include <parse/Sema.hpp>
1415
#include <testutil.hpp>
15-
#include <util/ADT.hpp>
1616

1717

1818
using namespace m;

unittest/IR/QueryGraphTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
#include "parse/Parser.hpp"
55
#include "parse/Sema.hpp"
66
#include "testutil.hpp"
7-
#include "util/ADT.hpp"
87
#include <mutable/catalog/Catalog.hpp>
98
#include <mutable/catalog/Type.hpp>
109
#include <mutable/mutable.hpp>
1110
#include <mutable/mutable.hpp>
11+
#include <mutable/util/ADT.hpp>
1212
#include <mutable/util/fn.hpp>
1313
#include <set>
1414
#include <unordered_set>

unittest/catalog/CardinalityEstimatorTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
#include "parse/Parser.hpp"
44
#include "parse/Sema.hpp"
5-
#include "util/ADT.hpp"
65
#include <cstring>
76
#include <mutable/catalog/CardinalityEstimator.hpp>
87
#include <mutable/catalog/Catalog.hpp>
98
#include <mutable/mutable.hpp>
9+
#include <mutable/util/ADT.hpp>
1010
#include <sstream>
1111

1212

unittest/util/ADTTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "catch2/catch.hpp"
22

3-
#include "util/ADT.hpp"
3+
#include <mutable/util/ADT.hpp>
44

55

66
using namespace m;

0 commit comments

Comments
 (0)