aboutsummaryrefslogtreecommitdiffhomepage
path: root/td/telegram/SetWithPosition.h
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2019-01-19 20:19:29 +0300
committerlevlam <levlam@telegram.org>2019-01-19 20:19:29 +0300
commitcdefe9b1ee5b8cc70c3885a8e114773e5d644225 (patch)
treeb97e6efc45f96a7500dd0f064041252d87434357 /td/telegram/SetWithPosition.h
parentb2ad399bc9e8745c68cf60c318fc2d2190bb03d8 (diff)
SetWithPosition CE and other fixes.
GitOrigin-RevId: 69278e7906c738924e1a4771b5b755ff349ea26f
Diffstat (limited to 'td/telegram/SetWithPosition.h')
-rw-r--r--td/telegram/SetWithPosition.h124
1 files changed, 54 insertions, 70 deletions
diff --git a/td/telegram/SetWithPosition.h b/td/telegram/SetWithPosition.h
index cff7449e7..915d3ed22 100644
--- a/td/telegram/SetWithPosition.h
+++ b/td/telegram/SetWithPosition.h
@@ -5,41 +5,58 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
+
#include "td/utils/common.h"
+#include "td/utils/logging.h"
+#include "td/utils/misc.h"
#include <set>
+#include <utility>
namespace td {
+
template <class T>
class FastSetWithPosition {
public:
- void add(int x) {
+ void add(T x) {
if (checked_.count(x) != 0) {
return;
}
not_checked_.insert(x);
}
- void remove(int x) {
+
+ void remove(T x) {
checked_.erase(x);
not_checked_.erase(x);
}
- bool has_next() {
+
+ bool has_next() const {
return !not_checked_.empty();
}
+
void reset_position() {
- not_checked_.insert(checked_.begin(), checked_.end());
- checked_ = {};
+ if (not_checked_.empty()) {
+ not_checked_ = std::move(checked_);
+ } else {
+ not_checked_.insert(checked_.begin(), checked_.end());
+ }
+ reset_to_empty(checked_);
}
T next() {
CHECK(has_next());
- auto res = *not_checked_.begin();
- not_checked_.erase(not_checked_.begin());
+ auto it = not_checked_.begin();
+ auto res = *it;
+ not_checked_.erase(it);
checked_.insert(res);
return res;
}
void merge(FastSetWithPosition &&other) {
+ if (this == &other) {
+ return;
+ }
+
if (size() < other.size()) {
std::swap(*this, other);
}
@@ -47,6 +64,7 @@ class FastSetWithPosition {
not_checked_.erase(x);
checked_.insert(x);
}
+
for (auto x : other.not_checked_) {
if (checked_.count(x) != 0) {
continue;
@@ -54,6 +72,7 @@ class FastSetWithPosition {
not_checked_.insert(x);
}
}
+
size_t size() const {
return checked_.size() + not_checked_.size();
}
@@ -66,7 +85,7 @@ class FastSetWithPosition {
template <class T>
class SetWithPosition {
public:
- void add(int x) {
+ void add(T x) {
if (fast_) {
fast_->add(x);
return;
@@ -74,7 +93,7 @@ class SetWithPosition {
if (!has_value_) {
value_ = x;
has_value_ = true;
- is_cheched_ = false;
+ is_checked_ = false;
return;
}
if (value_ == x) {
@@ -83,28 +102,31 @@ class SetWithPosition {
make_fast();
fast_->add(x);
}
- void remove(int x) {
+
+ void remove(T x) {
if (fast_) {
fast_->remove(x);
return;
}
if (has_value_ && value_ == x) {
has_value_ = false;
- is_cheched_ = false;
+ is_checked_ = false;
}
}
- bool has_next() {
+
+ bool has_next() const {
if (fast_) {
return fast_->has_next();
}
- return has_value_ && !is_cheched_;
+ return has_value_ && !is_checked_;
}
+
void reset_position() {
if (fast_) {
fast_->reset_position();
return;
}
- is_cheched_ = false;
+ is_checked_ = false;
}
T next() {
@@ -112,33 +134,46 @@ class SetWithPosition {
if (fast_) {
return fast_->next();
}
- is_cheched_ = true;
+ is_checked_ = true;
return value_;
}
void merge(SetWithPosition &&other) {
+ if (this == &other) {
+ return;
+ }
if (size() < other.size()) {
std::swap(*this, other);
}
if (other.size() == 0) {
return;
}
+ if (other.fast_ == nullptr && fast_ == nullptr && value_ == other.value_) {
+ is_checked_ |= other.is_checked_;
+ other.value_ = T();
+ other.has_value_ = false;
+ other.is_checked_ = false;
+ return;
+ }
make_fast();
other.make_fast();
fast_->merge(std::move(*other.fast_));
+ reset_to_empty(other);
}
+
size_t size() const {
if (fast_) {
return fast_->size();
}
- return has_value_;
+ return static_cast<size_t>(has_value_);
}
private:
- T value_;
+ T value_{};
bool has_value_{false};
- bool is_cheched_{false};
+ bool is_checked_{false};
unique_ptr<FastSetWithPosition<T>> fast_;
+
void make_fast() {
if (fast_) {
return;
@@ -146,61 +181,10 @@ class SetWithPosition {
fast_ = make_unique<FastSetWithPosition<T>>();
CHECK(has_value_);
fast_->add(value_);
- if (is_cheched_) {
+ if (is_checked_) {
fast_->next();
}
}
};
-template <class T>
-class OldSetWithPosition {
- public:
- void add(T value) {
- auto it = std::find(values_.begin(), values_.end(), value);
- if (it != end(values_)) {
- return;
- }
- values_.push_back(value);
- }
- void remove(T value) {
- auto it = std::find(values_.begin(), values_.end(), value);
- if (it == end(values_)) {
- return;
- }
- size_t i = it - values_.begin();
- values_.erase(it);
- if (pos_ > i) {
- pos_--;
- }
- }
- void reset_position() {
- pos_ = 0;
- }
- T next() {
- return values_[pos_++];
- }
- bool has_next() {
- return pos_ < values_.size();
- }
- void merge(OldSetWithPosition &&other) {
- OldSetWithPosition res;
- for (size_t i = 0; i < pos_; i++) {
- res.add(values_[i]);
- }
- for (size_t i = 0; i < other.pos_; i++) {
- res.add(other.values_[i]);
- }
- res.pos_ = res.values_.size();
- for (size_t i = pos_; i < values_.size(); i++) {
- res.add(values_[i]);
- }
- for (size_t i = other.pos_; i < other.values_.size(); i++) {
- res.add(other.values_[i]);
- }
- *this = std::move(res);
- }
- private:
- std::vector<T> values_;
- size_t pos_{0};
-};
} // namespace td