Use unordered map.

This commit is contained in:
chriseth 2022-03-24 01:37:41 +01:00
parent 1b44668b34
commit e4ad6ef39f
3 changed files with 86 additions and 3 deletions

View File

@ -123,7 +123,7 @@ private:
/// Stack of state, to allow for push()/pop().
std::vector<State> m_state{{State{}}};
std::map<SolvingState, LPResult, SolvingState::Compare> m_lpCache;
std::unordered_map<SolvingState, LPResult> m_lpCache;
};

View File

@ -504,7 +504,11 @@ bool Constraint::operator<(Constraint const& _other) const
for (size_t i = 0; i < max(data.size(), _other.data.size()); ++i)
if (rational diff = data.get(i) - _other.data.get(i))
{
//cout << "Exit after " << i << endl;
return diff < 0;
}
//cout << "full traversal of " << max(data.size(), _other.data.size()) << endl;
return false;
}
@ -516,7 +520,11 @@ bool Constraint::operator==(Constraint const& _other) const
for (size_t i = 0; i < max(data.size(), _other.data.size()); ++i)
if (data.get(i) != _other.data.get(i))
{
//cout << "Exit after " << i << endl;
return false;
}
//cout << "full traversal of " << max(data.size(), _other.data.size()) << endl;
return true;
}

View File

@ -24,6 +24,7 @@
#include <vector>
#include <variant>
#include <functional>
namespace solidity::util
{
@ -85,9 +86,83 @@ struct SolvingState
bool considerVariableNames;
};
bool operator==(SolvingState const& _other) const noexcept {
return bounds == _other.bounds && constraints == _other.constraints;
}
std::string toString() const;
};
}
template <class T>
inline void hashCombine(std::size_t& _seed, T const& _v)
{
std::hash<T> hasher;
_seed ^= hasher(_v) + 0x9e3779b9 + (_seed << 6) + (_seed >> 2);
}
template <class T>
inline void hashCombineVector(std::size_t& _seed, std::vector<T> const& _v)
{
hashCombine(_seed, _v.size());
for (auto const& x: _v)
hashCombine(_seed, x);
}
template<>
struct std::hash<solidity::util::SolvingState::Bounds>
{
std::size_t operator()(solidity::util::SolvingState::Bounds const& _bounds) const noexcept
{
std::size_t result = 0;
hashCombine(result, _bounds.lower);
hashCombine(result, _bounds.upper);
return result;
}
};
template<>
struct std::hash<solidity::util::LinearExpression>
{
std::size_t operator()(solidity::util::LinearExpression const& _linearExpression) const noexcept
{
std::size_t result = 0;
hashCombine(result, _linearExpression.size());
for (auto const& x: _linearExpression.enumerate())
hashCombine(result, x.second);
return result;
}
};
template<>
struct std::hash<solidity::util::Constraint>
{
std::size_t operator()(solidity::util::Constraint const& _constraint) const noexcept
{
std::size_t result = 0;
hashCombine(result, _constraint.equality);
hashCombine(result, _constraint.data);
return result;
}
};
template<>
struct std::hash<solidity::util::SolvingState>
{
std::size_t operator()(solidity::util::SolvingState const& _solvingState) const noexcept
{
std::size_t result = 0;
hashCombineVector(result, _solvingState.bounds);
hashCombineVector(result, _solvingState.constraints);
return result;
}
};
namespace solidity::util
{
enum class LPResult
{
Unknown,
@ -179,7 +254,7 @@ class LPSolver
{
public:
explicit LPSolver(bool _supportModels = true);
explicit LPSolver(std::map<SolvingState, LPResult, SolvingState::Compare>* _cache):
explicit LPSolver(std::unordered_map<SolvingState, LPResult>* _cache):
m_cache(_cache) {}
@ -216,7 +291,7 @@ private:
std::vector<size_t> m_subProblemsPerConstraint;
/// TODO also store the first infeasible subproblem?
/// TODO still retain the cache?
std::map<SolvingState, LPResult, SolvingState::Compare>* m_cache = nullptr;
std::unordered_map<SolvingState, LPResult>* m_cache = nullptr;
};