OR-Tools  9.3
model_summary.h
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_MATH_OPT_CORE_MODEL_SUMMARY_H_
15#define OR_TOOLS_MATH_OPT_CORE_MODEL_SUMMARY_H_
16
17#include <cstdint>
18#include <initializer_list>
19#include <list>
20#include <string>
21#include <utility>
22
23#include "absl/container/flat_hash_map.h"
24#include "absl/strings/string_view.h"
28
29namespace operations_research {
30namespace math_opt {
31
32// Maintains a bidirectional mapping between names and ids, e.g. as used for
33// variables and linear constraints.
34//
35// The following invariants are enforced:
36// * Ids must be unique and increasing (in insertion order).
37// * Ids are non-negative.
38// * Ids are not equal to std::numeric_limits<int64_t>::max()
39// * Ids removed are never reused.
40// * Names must be either empty or unique.
42 public:
43 IdNameBiMap() = default;
44
45 // This constructor CHECKs that the input ids are sorted in increasing
46 // order. This constructor is expected to be used only for unit tests of
47 // validation code.
48 IdNameBiMap(std::initializer_list<std::pair<int64_t, absl::string_view>> ids);
49
50 // Inserts the provided id and associate the provided name to it. CHECKs that
51 // id >= next_free_id() and that when the name is nonempty it is not already
52 // present. As a side effect it updates next_free_id to id + 1.
53 inline void Insert(int64_t id, std::string name);
54
55 // Removes the given id. CHECKs that it is present.
56 inline void Erase(int64_t id);
57
58 inline bool HasId(int64_t id) const;
59 inline bool HasName(absl::string_view name) const;
60 inline bool Empty() const;
61 inline int Size() const;
62
63 // The next id that has never been used (0 initially since ids are
64 // non-negative).
65 inline int64_t next_free_id() const;
66
67 // Updates next_free_id(). CHECKs that the provided id is greater than any
68 // exiting id and non negative.
69 //
70 // In practice this should only be used to increase the next_free_id() value
71 // in cases where a ModelSummary is built with an existing model but we know
72 // some ids of removed elements have already been used.
73 inline void SetNextFreeId(int64_t new_next_free_id);
74
75 // Iteration order is in increasing id order.
77 return id_to_name_;
78 }
79 const absl::flat_hash_map<absl::string_view, int64_t>& nonempty_name_to_id()
80 const {
81 return nonempty_name_to_id_;
82 }
83
84 private:
85 // Next unused id.
86 int64_t next_free_id_ = 0;
87
88 // Pointer stability for name strings and iterating in insertion order are
89 // both needed (so we do not use flat_hash_map).
91 absl::flat_hash_map<absl::string_view, int64_t> nonempty_name_to_id_;
92};
93
97};
98
100// Inline function implementations
102
103void IdNameBiMap::Insert(const int64_t id, std::string name) {
104 CHECK_GE(id, next_free_id_);
106 next_free_id_ = id + 1;
107
108 const auto [it, success] = id_to_name_.emplace(id, std::move(name));
109 CHECK(success) << "id: " << id;
110 const absl::string_view name_view(it->second);
111 if (!name_view.empty()) {
112 gtl::InsertOrDie(&nonempty_name_to_id_, name_view, id);
113 }
114}
115
116void IdNameBiMap::Erase(const int64_t id) {
117 const auto it = id_to_name_.find(id);
118 CHECK(it != id_to_name_.end()) << id;
119 const absl::string_view name_view(it->second);
120 if (!name_view.empty()) {
121 CHECK_EQ(1, nonempty_name_to_id_.erase(name_view))
122 << "name: " << name_view << " id: " << id;
123 }
124 id_to_name_.erase(it);
125}
126bool IdNameBiMap::HasId(const int64_t id) const {
127 return id_to_name_.contains(id);
128}
129bool IdNameBiMap::HasName(const absl::string_view name) const {
130 CHECK(!name.empty());
131 return nonempty_name_to_id_.contains(name);
132}
133
134bool IdNameBiMap::Empty() const { return id_to_name_.empty(); }
135
136int IdNameBiMap::Size() const { return id_to_name_.size(); }
137
138int64_t IdNameBiMap::next_free_id() const { return next_free_id_; }
139
140void IdNameBiMap::SetNextFreeId(const int64_t new_next_free_id) {
141 if (!Empty()) {
142 const int64_t largest_id = id_to_name_.back().first;
143 CHECK_GT(new_next_free_id, largest_id);
144 } else {
145 CHECK_GE(new_next_free_id, 0);
146 }
147 next_free_id_ = new_next_free_id;
148}
149
150} // namespace math_opt
151} // namespace operations_research
152
153#endif // OR_TOOLS_MATH_OPT_CORE_MODEL_SUMMARY_H_
int64_t max
Definition: alldiff_cst.cc:140
#define CHECK(condition)
Definition: base/logging.h:495
#define CHECK_LT(val1, val2)
Definition: base/logging.h:706
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:703
#define CHECK_GE(val1, val2)
Definition: base/logging.h:707
#define CHECK_GT(val1, val2)
Definition: base/logging.h:708
bool contains(const key_arg< K > &key) const
size_type size() const
iterator find(const key_arg< K > &key)
size_type erase(const key_arg< K > &key)
std::pair< iterator, bool > emplace(Args &&... args)
bool HasName(absl::string_view name) const
const gtl::linked_hash_map< int64_t, std::string > & id_to_name() const
Definition: model_summary.h:76
void SetNextFreeId(int64_t new_next_free_id)
void Insert(int64_t id, std::string name)
const absl::flat_hash_map< absl::string_view, int64_t > & nonempty_name_to_id() const
Definition: model_summary.h:79
const std::string name
void InsertOrDie(Collection *const collection, const typename Collection::value_type &value)
Definition: map_util.h:154
Collection of objects used to extend the Constraint Solver library.