15 #ifndef OR_TOOLS_UTIL_REV_H_
16 #define OR_TOOLS_UTIL_REV_H_
20 #include "absl/container/flat_hash_map.h"
54 int Level()
const {
return end_of_level_.size(); }
62 if (end_of_level_.empty())
return;
63 stack_.push_back({object, *
object});
72 if (*stamp == stamp_)
return;
79 std::vector<int> end_of_level_;
83 std::vector<std::pair<T*, T>> stack_;
87 template <
class IndexType,
class T>
97 if (!end_of_level_.empty()) stack_.push_back({
index, vector_[
index]});
98 return vector_[
index];
110 int Level()
const {
return end_of_level_.size(); }
114 if (level ==
Level())
return;
115 if (level <
Level()) {
116 const int index = end_of_level_[level];
117 end_of_level_.resize(level);
118 for (
int i = stack_.size() - 1; i >=
index; --i) {
119 vector_[stack_[i].first] = stack_[i].second;
121 stack_.resize(
index);
123 end_of_level_.resize(level, stack_.size());
128 std::vector<int> end_of_level_;
129 std::vector<std::pair<IndexType, T>> stack_;
136 if (level == Level())
return;
138 if (level < Level()) {
139 const int index = end_of_level_[level];
140 end_of_level_.resize(level);
141 for (
int i = stack_.size() - 1; i >=
index; --i) {
142 *stack_[i].first = stack_[i].second;
144 stack_.resize(
index);
146 end_of_level_.resize(level, stack_.size());
169 int Level()
const {
return first_op_index_of_next_level_.size(); }
180 int size()
const {
return map_.size(); }
181 bool empty()
const {
return map_.empty(); }
192 struct UndoOperation {
201 std::vector<UndoOperation> operations_;
202 std::vector<int> first_op_index_of_next_level_;
208 if (level < Level()) {
209 const int backtrack_level = first_op_index_of_next_level_[level];
210 first_op_index_of_next_level_.resize(level);
211 while (operations_.size() > backtrack_level) {
212 const UndoOperation& to_undo = operations_.back();
213 if (to_undo.is_deletion) {
214 map_.erase(to_undo.key);
216 map_.insert({to_undo.key, to_undo.value}).first->second = to_undo.value;
218 operations_.pop_back();
224 first_op_index_of_next_level_.resize(level, operations_.size());
229 const auto iter = map_.find(key);
230 if (iter == map_.end())
LOG(
FATAL) <<
"key not present: '" << key <<
"'.";
232 operations_.push_back({
false, key, iter->second});
239 auto insertion_result = map_.insert({key,
value});
241 if (insertion_result.second) {
243 operations_.push_back({
true, key});
246 operations_.push_back({
false, key, insertion_result.first->second});
249 insertion_result.first->second =
value;
253 template <
class Key,
class Value>
262 const std::vector<Value>&
Values(Key key)
const;
265 std::vector<Value> empty_values_;
270 absl::flat_hash_map<Key, std::vector<Value>> map_;
273 std::vector<Key> added_keys_;
274 std::vector<int> first_added_key_of_next_level_;
277 template <
class Key,
class Value>
280 if (level < first_added_key_of_next_level_.size()) {
281 const int backtrack_level = first_added_key_of_next_level_[level];
282 first_added_key_of_next_level_.resize(level);
283 while (added_keys_.size() > backtrack_level) {
284 auto it = map_.find(added_keys_.back());
285 if (it->second.size() > 1) {
286 it->second.pop_back();
290 added_keys_.pop_back();
296 first_added_key_of_next_level_.resize(level, added_keys_.size());
299 template <
class Key,
class Value>
302 const auto it = map_.find(key);
303 if (it != map_.end())
return it->second;
304 return empty_values_;
307 template <
class Key,
class Value>
309 if (!first_added_key_of_next_level_.empty()) {
310 added_keys_.push_back(key);
312 map_[key].push_back(
value);
317 #endif // OR_TOOLS_UTIL_REV_H_