A set of benchmarks to compare a new prototype MiniZinc implementation
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3/*
4 * Main authors:
5 * Guido Tack <guido.tack@monash.edu>
6 */
7
8/* This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11
12#ifndef __MINIZINC_HASH_HH__
13#define __MINIZINC_HASH_HH__
14
15#include <minizinc/ast.hh>
16#include <minizinc/exception.hh>
17
18#include <unordered_map>
19#include <unordered_set>
20
21namespace MiniZinc {
22
23/// Hash class for expressions
24struct ExpressionHash {
25 size_t operator()(const Expression* e) const { return Expression::hash(e); }
26};
27
28/// Equality test for expressions
29struct ExpressionEq {
30 bool operator()(const Expression* e0, const Expression* e1) const {
31 return Expression::equal(e0, e1);
32 }
33};
34
35/// Hash map from expression to \a T
36template <class T>
37class ExpressionMap {
38protected:
39 /// The underlying map implementation
40 std::unordered_map<Expression*, T, ExpressionHash, ExpressionEq> _m;
41
42public:
43 /// Iterator type
44 typedef
45 typename std::unordered_map<Expression*, T, ExpressionHash, ExpressionEq>::iterator iterator;
46 /// Insert mapping from \a e to \a t
47 iterator insert(Expression* e, const T& t) {
48 assert(e != NULL);
49 return _m.insert(std::pair<Expression*, T>(e, t)).first;
50 }
51 /// Find \a e in map
52 iterator find(Expression* e) { return _m.find(e); }
53 /// Begin of iterator
54 iterator begin(void) { return _m.begin(); }
55 /// End of iterator
56 iterator end(void) { return _m.end(); }
57 /// Remove binding of \a e from map
58 void remove(Expression* e) { _m.erase(e); }
59 /// Remove all elements from the map
60 void clear(void) { _m.clear(); }
61};
62
63/// Equality test for identifiers
64struct IdEq {
65 bool operator()(const Id* e0, const Id* e1) const {
66 if (e0->idn() == e1->idn()) {
67 if (e0->idn() == -1) return e0->v() == e1->v();
68 return true;
69 }
70 return false;
71 }
72};
73
74/// Hash map from identifier to \a T
75template <class T>
76class IdMap {
77protected:
78 /// The underlying map implementation
79 std::unordered_map<Id*, T, ExpressionHash, IdEq> _m;
80
81public:
82 /// Iterator type
83 typedef typename std::unordered_map<Id*, T, ExpressionHash, IdEq>::iterator iterator;
84 /// Insert mapping from \a e to \a t
85 void insert(Id* e, const T& t) {
86 assert(e != NULL);
87 _m.insert(std::pair<Id*, T>(e, t));
88 }
89 /// Find \a e in map
90 iterator find(Id* e) { return _m.find(e); }
91 /// Begin of iterator
92 iterator begin(void) { return _m.begin(); }
93 /// End of iterator
94 iterator end(void) { return _m.end(); }
95 /// Remove binding of \a e from map
96 void remove(Id* e) { _m.erase(e); }
97 /// Return number of elements in the map
98 int size(void) const { return _m.size(); }
99 /// Remove all elements from the map
100 void clear(void) { _m.clear(); }
101 T& get(Id* ident) {
102 iterator it = find(ident);
103 // assert(it != _m.end());
104 if (_m.end() == it) { // Changing so it stays in Release version
105 std::string msg = "Id ";
106 // if (ident) // could be a segfault...
107 // msg += ident->v().c_str();
108 msg += " not found";
109 throw InternalError(msg);
110 }
111 return it->second;
112 }
113};
114
115/// Hash class for KeepAlive objects
116struct KAHash {
117 size_t operator()(const KeepAlive& e) const { return Expression::hash(e()); }
118};
119
120/// Equality test for KeepAlive objects
121struct KAEq {
122 bool operator()(const KeepAlive& e0, const KeepAlive& e1) const {
123 return Expression::equal(e0(), e1());
124 }
125};
126
127/// Hash map from KeepAlive to \a T
128template <class T>
129class KeepAliveMap {
130protected:
131 /// The underlying map implementation
132 std::unordered_map<KeepAlive, T, KAHash, KAEq> _m;
133
134public:
135 /// Iterator type
136 typedef typename std::unordered_map<KeepAlive, T, KAHash, KAEq>::iterator iterator;
137 /// Insert mapping from \a e to \a t
138 void insert(KeepAlive& e, const T& t) {
139 assert(e() != NULL);
140 _m.insert(std::pair<KeepAlive, T>(e, t));
141 }
142 /// Find \a e in map
143 iterator find(KeepAlive& e) { return _m.find(e); }
144 /// Begin of iterator
145 iterator begin(void) { return _m.begin(); }
146 /// End of iterator
147 iterator end(void) { return _m.end(); }
148 /// Remove binding of \a e from map
149 void remove(KeepAlive& e) { _m.erase(e); }
150 void clear() { _m.clear(); }
151 template <class D>
152 void dump(void) {
153 for (iterator i = _m.begin(); i != _m.end(); ++i) {
154 std::cerr << D::k(i->first()) << ": " << D::d(i->second) << std::endl;
155 }
156 }
157};
158
159class ExpressionSetIter
160 : public std::unordered_set<Expression*, ExpressionHash, ExpressionEq>::iterator {
161protected:
162 bool _empty;
163 typedef std::unordered_set<Expression*, ExpressionHash, ExpressionEq>::iterator Iter;
164
165public:
166 ExpressionSetIter(void) : _empty(false) {}
167 ExpressionSetIter(bool) : _empty(true) {}
168 ExpressionSetIter(const Iter& i) : Iter(i), _empty(false) {}
169 bool operator==(const ExpressionSetIter& i) const {
170 return (_empty && i._empty) || static_cast<const Iter&>(*this) == static_cast<const Iter&>(i);
171 }
172 bool operator!=(const ExpressionSetIter& i) const { return !operator==(i); }
173};
174
175/// Hash set for expressions
176class ExpressionSet {
177protected:
178 /// The underlying set implementation
179 std::unordered_set<Expression*, ExpressionHash, ExpressionEq> _s;
180
181public:
182 /// Insert \a e
183 void insert(Expression* e) {
184 assert(e != NULL);
185 _s.insert(e);
186 }
187 /// Find \a e in map
188 ExpressionSetIter find(Expression* e) { return _s.find(e); }
189 /// Begin of iterator
190 ExpressionSetIter begin(void) { return _s.begin(); }
191 /// End of iterator
192 ExpressionSetIter end(void) { return _s.end(); }
193 /// Remove binding of \a e from map
194 void remove(Expression* e) { _s.erase(e); }
195 bool contains(Expression* e) { return find(e) != end(); }
196 /// Remove all elements from the map
197 void clear(void) { _s.clear(); }
198 bool isEmpty(void) const { return _s.begin() == _s.end(); }
199};
200
201} // namespace MiniZinc
202
203#endif