14#ifndef OR_TOOLS_MATH_OPT_STORAGE_ATOMIC_CONSTRAINT_STORAGE_H_
15#define OR_TOOLS_MATH_OPT_STORAGE_ATOMIC_CONSTRAINT_STORAGE_H_
21#include "absl/algorithm/container.h"
22#include "absl/container/flat_hash_map.h"
23#include "absl/container/flat_hash_set.h"
24#include "absl/log/check.h"
25#include "google/protobuf/map.h"
69template <
typename Constra
intData>
72 using IdType =
typename ConstraintData::IdType;
73 using ProtoType =
typename ConstraintData::ProtoType;
97 const google::protobuf::Map<int64_t, ProtoType>& constraints);
100 template <
typename DiffIter>
108 int64_t
size()
const {
return constraint_data_.size(); }
115 next_id_ = std::max(minimum, next_id_);
122 const VariableId variable_id)
const {
136 google::protobuf::Map<int64_t, ProtoType>
Proto()
const {
137 google::protobuf::Map<int64_t, ProtoType> constraints;
138 for (
const auto& [
id,
data] : constraint_data_) {
139 constraints[
id.value()] =
data.Proto();
147 return constraint_data_.at(
id);
159 typename ConstraintData::UpdatesProtoType
Update(
const Diff& diff)
const;
166 absl::flat_hash_map<IdType, ConstraintData> constraint_data_;
168 absl::flat_hash_map<VariableId, absl::flat_hash_set<IdType>>
169 constraints_by_variable_;
177template <
typename IdType>
178struct AtomicConstraintTraits {
186template <
typename Constra
intData>
190 const std::vector<VariableId> vars = constraint.RelatedVariables();
191 const IdType
id = next_id_++;
192 CHECK(constraint_data_.insert({id, std::move(constraint)}).second);
193 for (
const VariableId v : vars) {
194 constraints_by_variable_[v].insert(
id);
199template <
typename Constra
intData>
201 const google::protobuf::Map<int64_t, ProtoType>& constraints) {
203 const IdType id(raw_id);
204 CHECK_GE(
id, next_id())
205 <<
"constraint ID in map: " << raw_id
206 <<
" is smaller than next_id(): " << next_id().value();
207 ensure_next_id_at_least(
id);
208 AddConstraint(ConstraintData::FromProto(constraints.at(raw_id)));
212template <
typename Constra
intData>
213template <
typename DiffIter>
215 IdType
id,
const iterator_range<DiffIter>& diffs) {
216 for (Diff& diff : diffs) {
218 if (
id >= diff.checkpoint) {
221 diff.deleted_constraints.insert(
id);
223 const auto data = constraint_data_.find(
id);
224 CHECK(data != constraint_data_.end());
225 for (
const VariableId v : data->second.RelatedVariables()) {
226 constraints_by_variable_[v].erase(
id);
228 constraint_data_.erase(
id);
231template <
typename Constra
intData>
233 VariableId variable_id) {
234 const auto it = constraints_by_variable_.find(variable_id);
235 if (it == constraints_by_variable_.end()) {
238 for (
const IdType constraint_id : it->second) {
239 constraint_data_.at(constraint_id).DeleteVariable(variable_id);
241 constraints_by_variable_.erase(it);
244template <
typename Constra
intData>
245std::vector<typename AtomicConstraintStorage<ConstraintData>::IdType>
247 std::vector<IdType> result;
248 for (
const auto& [
id, _] : constraint_data_) {
249 result.push_back(
id);
254template <
typename Constra
intData>
255std::vector<typename AtomicConstraintStorage<ConstraintData>::IdType>
257 std::vector<IdType> result = Constraints();
258 absl::c_sort(result);
262template <
typename Constra
intData>
264 const Diff& diff)
const {
265 return next_id_ <= diff.checkpoint && diff.deleted_constraints.empty();
268template <
typename Constra
intData>
275template <
typename Constra
intData>
276typename ConstraintData::UpdatesProtoType
278 UpdatesProtoType update;
279 for (
const IdType deleted_id : diff.deleted_constraints) {
280 update.mutable_deleted_constraint_ids()->Add(deleted_id.value());
282 absl::c_sort(*update.mutable_deleted_constraint_ids());
283 for (
const IdType
id :
286 (*update.mutable_new_constraints())[
id.value()] = data(
id).Proto();
bool diff_is_empty(const Diff &diff) const
ConstraintData::UpdatesProtoType Update(const Diff &diff) const
Return a proto representation of the current update.
typename ConstraintData::IdType IdType
google::protobuf::Map< int64_t, ProtoType > Proto() const
Returns a proto representation of the constraint class.
void ensure_next_id_at_least(const IdType minimum)
Sets the next variable id to be the maximum of next_id() and minimum.
typename ConstraintData::UpdatesProtoType UpdatesProtoType
bool contains(const IdType id) const
Returns true if this id has been created and not yet deleted.
std::vector< IdType > Constraints() const
The ids in use (not deleted). The order is not defined.
void AdvanceCheckpointInDiff(Diff &diff) const
Updates the checkpoint and clears all stored changes in diff.
typename ConstraintData::ProtoType ProtoType
std::vector< IdType > SortedConstraints() const
void AddConstraints(const google::protobuf::Map< int64_t, ProtoType > &constraints)
IdType next_id() const
The smallest ID which is valid for a new constraint.
void DeleteVariable(VariableId variable_id)
Delete a single variable from each constraint in the storage.
const absl::flat_hash_set< IdType > & RelatedConstraints(const VariableId variable_id) const
IdType AddConstraint(ConstraintData constraint)
Add a single constraint to the storage.
void Delete(IdType id, const iterator_range< DiffIter > &diffs)
Delete a single constraint.
const ConstraintData & data(const IdType id) const
const MapUtilMappedT< Collection > & FindWithDefault(const Collection &collection, const KeyType &key, const MapUtilMappedT< Collection > &value)
An object oriented wrapper for quadratic constraints in ModelStorage.
std::vector< K > SortedMapKeys(const absl::flat_hash_map< K, V > &in_map)
StrongIntRange< IntType > MakeStrongIntRange(IntType end)
absl::flat_hash_set< IdType > deleted_constraints
Diff(const AtomicConstraintStorage< ConstraintData > &storage)