diff options
| author | levlam <levlam@telegram.org> | 2019-01-19 20:19:29 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2019-01-19 20:19:29 +0300 |
| commit | cdefe9b1ee5b8cc70c3885a8e114773e5d644225 (patch) | |
| tree | b97e6efc45f96a7500dd0f064041252d87434357 /td/telegram/SetWithPosition.h | |
| parent | b2ad399bc9e8745c68cf60c318fc2d2190bb03d8 (diff) | |
SetWithPosition CE and other fixes.
GitOrigin-RevId: 69278e7906c738924e1a4771b5b755ff349ea26f
Diffstat (limited to 'td/telegram/SetWithPosition.h')
| -rw-r--r-- | td/telegram/SetWithPosition.h | 124 |
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 |
