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_);
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_;
193 CHECK(constraint_data_.insert({id, std::move(constraint)}).second);
195 constraints_by_variable_[v].insert(
id);
200template <
typename Constra
intData>
202 const google::protobuf::Map<int64_t, ProtoType>& constraints) {
204 const IdType id(raw_id);
206 <<
"constraint ID in map: " << raw_id
207 <<
" is smaller than next_id(): " <<
next_id().value();
209 AddConstraint(ConstraintData::FromProto(constraints.at(raw_id)));
213template <
typename Constra
intData>
214template <
typename DiffIter>
216 IdType
id,
const iterator_range<DiffIter>& diffs) {
217 for (Diff& diff : diffs) {
219 if (
id >= diff.checkpoint) {
222 diff.deleted_constraints.insert(
id);
224 const auto data = constraint_data_.find(
id);
225 CHECK(data != constraint_data_.end());
226 for (
const VariableId v : data->second.RelatedVariables()) {
227 constraints_by_variable_[v].erase(
id);
229 constraint_data_.erase(
id);
232template <
typename Constra
intData>
235 const auto it = constraints_by_variable_.find(variable_id);
236 if (it == constraints_by_variable_.end()) {
239 for (
const IdType constraint_id : it->second) {
240 constraint_data_.at(constraint_id).DeleteVariable(variable_id);
242 constraints_by_variable_.erase(it);
245template <
typename Constra
intData>
246std::vector<typename AtomicConstraintStorage<ConstraintData>::IdType>
248 std::vector<IdType> result;
249 for (
const auto& [
id, _] : constraint_data_) {
250 result.push_back(
id);
255template <
typename Constra
intData>
256std::vector<typename AtomicConstraintStorage<ConstraintData>::IdType>
258 std::vector<IdType> result = Constraints();
259 absl::c_sort(result);
263template <
typename Constra
intData>
265 const Diff& diff)
const {
266 return next_id_ <= diff.
checkpoint && diff.deleted_constraints.empty();
269template <
typename Constra
intData>
276template <
typename Constra
intData>
277typename ConstraintData::UpdatesProtoType
279 UpdatesProtoType update;
280 for (
const IdType deleted_id : diff.deleted_constraints) {
281 update.mutable_deleted_constraint_ids()->Add(deleted_id.value());
283 absl::c_sort(*update.mutable_deleted_constraint_ids());
284 for (
const IdType
id :
285 util_intops::MakeStrongIntRange(diff.
checkpoint, next_id_)) {
287 (*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
int64_t checkpoint(const ElementType e) const
const MapUtilMappedT< Collection > & FindWithDefault(const Collection &collection, const KeyType &key, const MapUtilMappedT< Collection > &value)
An object oriented wrapper for quadratic constraints in ModelStorage.
ElementId< ElementType::kVariable > VariableId
std::vector< K > SortedMapKeys(const absl::flat_hash_map< K, V > &in_map)
absl::flat_hash_set< IdType > deleted_constraints
Diff(const AtomicConstraintStorage< ConstraintData > &storage)