SetWithPosition CE and other fixes.
GitOrigin-RevId: 69278e7906c738924e1a4771b5b755ff349ea26f
This commit is contained in:
parent
b2ad399bc9
commit
cdefe9b1ee
@ -11,14 +11,12 @@
|
|||||||
#include "td/telegram/files/FileManager.h"
|
#include "td/telegram/files/FileManager.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
|
#include "td/telegram/WallpaperManager.h"
|
||||||
#include "td/telegram/WebPagesManager.h"
|
#include "td/telegram/WebPagesManager.h"
|
||||||
|
|
||||||
#include "td/actor/MultiPromise.h"
|
#include "td/utils/logging.h"
|
||||||
|
|
||||||
#include "td/utils/format.h"
|
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/overloaded.h"
|
#include "td/utils/overloaded.h"
|
||||||
#include "td/utils/Variant.h"
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
@ -9,15 +9,16 @@
|
|||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/PromiseFuture.h"
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
|
||||||
#include "td/telegram/ChatId.h"
|
|
||||||
#include "td/telegram/ChannelId.h"
|
#include "td/telegram/ChannelId.h"
|
||||||
|
#include "td/telegram/ChatId.h"
|
||||||
#include "td/telegram/files/FileId.h"
|
#include "td/telegram/files/FileId.h"
|
||||||
#include "td/telegram/files/FileManager.h"
|
|
||||||
#include "td/telegram/files/FileSourceId.h"
|
#include "td/telegram/files/FileSourceId.h"
|
||||||
#include "td/telegram/MessageId.h"
|
#include "td/telegram/MessageId.h"
|
||||||
#include "td/telegram/SetWithPosition.h"
|
#include "td/telegram/SetWithPosition.h"
|
||||||
#include "td/telegram/UserId.h"
|
#include "td/telegram/UserId.h"
|
||||||
|
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
#include "td/utils/Variant.h"
|
#include "td/utils/Variant.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -3158,8 +3158,7 @@ static auto secret_to_telegram(secret_api::fileLocationUnavailable &file_locatio
|
|||||||
// fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
// fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||||
static auto secret_to_telegram(secret_api::fileLocation &file_location) {
|
static auto secret_to_telegram(secret_api::fileLocation &file_location) {
|
||||||
return make_tl_object<telegram_api::fileLocation>(file_location.dc_id_, file_location.volume_id_,
|
return make_tl_object<telegram_api::fileLocation>(file_location.dc_id_, file_location.volume_id_,
|
||||||
file_location.local_id_, file_location.secret_,
|
file_location.local_id_, file_location.secret_, BufferSlice());
|
||||||
BufferSlice());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// photoSizeEmpty#e17e23c type:string = PhotoSize;
|
// photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||||
@ -3307,9 +3306,9 @@ static auto secret_to_telegram_document(secret_api::decryptedMessageMediaExterna
|
|||||||
if (!clean_input_string(from.mime_type_)) {
|
if (!clean_input_string(from.mime_type_)) {
|
||||||
from.mime_type_.clear();
|
from.mime_type_.clear();
|
||||||
}
|
}
|
||||||
return make_tl_object<telegram_api::document>(
|
return make_tl_object<telegram_api::document>(from.id_, from.access_hash_, BufferSlice(), from.date_, from.mime_type_,
|
||||||
from.id_, from.access_hash_, BufferSlice(), from.date_, from.mime_type_, from.size_,
|
from.size_, secret_to_telegram<telegram_api::PhotoSize>(*from.thumb_),
|
||||||
secret_to_telegram<telegram_api::PhotoSize>(*from.thumb_), from.dc_id_, secret_to_telegram(from.attributes_));
|
from.dc_id_, secret_to_telegram(from.attributes_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ToT, class FromT>
|
template <class ToT, class FromT>
|
||||||
|
@ -5,41 +5,58 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/misc.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class FastSetWithPosition {
|
class FastSetWithPosition {
|
||||||
public:
|
public:
|
||||||
void add(int x) {
|
void add(T x) {
|
||||||
if (checked_.count(x) != 0) {
|
if (checked_.count(x) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
not_checked_.insert(x);
|
not_checked_.insert(x);
|
||||||
}
|
}
|
||||||
void remove(int x) {
|
|
||||||
|
void remove(T x) {
|
||||||
checked_.erase(x);
|
checked_.erase(x);
|
||||||
not_checked_.erase(x);
|
not_checked_.erase(x);
|
||||||
}
|
}
|
||||||
bool has_next() {
|
|
||||||
|
bool has_next() const {
|
||||||
return !not_checked_.empty();
|
return !not_checked_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_position() {
|
void reset_position() {
|
||||||
|
if (not_checked_.empty()) {
|
||||||
|
not_checked_ = std::move(checked_);
|
||||||
|
} else {
|
||||||
not_checked_.insert(checked_.begin(), checked_.end());
|
not_checked_.insert(checked_.begin(), checked_.end());
|
||||||
checked_ = {};
|
}
|
||||||
|
reset_to_empty(checked_);
|
||||||
}
|
}
|
||||||
|
|
||||||
T next() {
|
T next() {
|
||||||
CHECK(has_next());
|
CHECK(has_next());
|
||||||
auto res = *not_checked_.begin();
|
auto it = not_checked_.begin();
|
||||||
not_checked_.erase(not_checked_.begin());
|
auto res = *it;
|
||||||
|
not_checked_.erase(it);
|
||||||
checked_.insert(res);
|
checked_.insert(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void merge(FastSetWithPosition &&other) {
|
void merge(FastSetWithPosition &&other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (size() < other.size()) {
|
if (size() < other.size()) {
|
||||||
std::swap(*this, other);
|
std::swap(*this, other);
|
||||||
}
|
}
|
||||||
@ -47,6 +64,7 @@ class FastSetWithPosition {
|
|||||||
not_checked_.erase(x);
|
not_checked_.erase(x);
|
||||||
checked_.insert(x);
|
checked_.insert(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto x : other.not_checked_) {
|
for (auto x : other.not_checked_) {
|
||||||
if (checked_.count(x) != 0) {
|
if (checked_.count(x) != 0) {
|
||||||
continue;
|
continue;
|
||||||
@ -54,6 +72,7 @@ class FastSetWithPosition {
|
|||||||
not_checked_.insert(x);
|
not_checked_.insert(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return checked_.size() + not_checked_.size();
|
return checked_.size() + not_checked_.size();
|
||||||
}
|
}
|
||||||
@ -66,7 +85,7 @@ class FastSetWithPosition {
|
|||||||
template <class T>
|
template <class T>
|
||||||
class SetWithPosition {
|
class SetWithPosition {
|
||||||
public:
|
public:
|
||||||
void add(int x) {
|
void add(T x) {
|
||||||
if (fast_) {
|
if (fast_) {
|
||||||
fast_->add(x);
|
fast_->add(x);
|
||||||
return;
|
return;
|
||||||
@ -74,7 +93,7 @@ class SetWithPosition {
|
|||||||
if (!has_value_) {
|
if (!has_value_) {
|
||||||
value_ = x;
|
value_ = x;
|
||||||
has_value_ = true;
|
has_value_ = true;
|
||||||
is_cheched_ = false;
|
is_checked_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (value_ == x) {
|
if (value_ == x) {
|
||||||
@ -83,28 +102,31 @@ class SetWithPosition {
|
|||||||
make_fast();
|
make_fast();
|
||||||
fast_->add(x);
|
fast_->add(x);
|
||||||
}
|
}
|
||||||
void remove(int x) {
|
|
||||||
|
void remove(T x) {
|
||||||
if (fast_) {
|
if (fast_) {
|
||||||
fast_->remove(x);
|
fast_->remove(x);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (has_value_ && value_ == x) {
|
if (has_value_ && value_ == x) {
|
||||||
has_value_ = false;
|
has_value_ = false;
|
||||||
is_cheched_ = false;
|
is_checked_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool has_next() {
|
|
||||||
|
bool has_next() const {
|
||||||
if (fast_) {
|
if (fast_) {
|
||||||
return fast_->has_next();
|
return fast_->has_next();
|
||||||
}
|
}
|
||||||
return has_value_ && !is_cheched_;
|
return has_value_ && !is_checked_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_position() {
|
void reset_position() {
|
||||||
if (fast_) {
|
if (fast_) {
|
||||||
fast_->reset_position();
|
fast_->reset_position();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
is_cheched_ = false;
|
is_checked_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
T next() {
|
T next() {
|
||||||
@ -112,33 +134,46 @@ class SetWithPosition {
|
|||||||
if (fast_) {
|
if (fast_) {
|
||||||
return fast_->next();
|
return fast_->next();
|
||||||
}
|
}
|
||||||
is_cheched_ = true;
|
is_checked_ = true;
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void merge(SetWithPosition &&other) {
|
void merge(SetWithPosition &&other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (size() < other.size()) {
|
if (size() < other.size()) {
|
||||||
std::swap(*this, other);
|
std::swap(*this, other);
|
||||||
}
|
}
|
||||||
if (other.size() == 0) {
|
if (other.size() == 0) {
|
||||||
return;
|
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();
|
make_fast();
|
||||||
other.make_fast();
|
other.make_fast();
|
||||||
fast_->merge(std::move(*other.fast_));
|
fast_->merge(std::move(*other.fast_));
|
||||||
|
reset_to_empty(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
if (fast_) {
|
if (fast_) {
|
||||||
return fast_->size();
|
return fast_->size();
|
||||||
}
|
}
|
||||||
return has_value_;
|
return static_cast<size_t>(has_value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T value_;
|
T value_{};
|
||||||
bool has_value_{false};
|
bool has_value_{false};
|
||||||
bool is_cheched_{false};
|
bool is_checked_{false};
|
||||||
unique_ptr<FastSetWithPosition<T>> fast_;
|
unique_ptr<FastSetWithPosition<T>> fast_;
|
||||||
|
|
||||||
void make_fast() {
|
void make_fast() {
|
||||||
if (fast_) {
|
if (fast_) {
|
||||||
return;
|
return;
|
||||||
@ -146,61 +181,10 @@ class SetWithPosition {
|
|||||||
fast_ = make_unique<FastSetWithPosition<T>>();
|
fast_ = make_unique<FastSetWithPosition<T>>();
|
||||||
CHECK(has_value_);
|
CHECK(has_value_);
|
||||||
fast_->add(value_);
|
fast_->add(value_);
|
||||||
if (is_cheched_) {
|
if (is_checked_) {
|
||||||
fast_->next();
|
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
|
} // namespace td
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
#include "td/telegram/TdParameters.h"
|
#include "td/telegram/TdParameters.h"
|
||||||
|
|
||||||
#include "td/db/binlog/BinlogInterface.h"
|
|
||||||
#include "td/db/binlog/BinlogEvent.h"
|
#include "td/db/binlog/BinlogEvent.h"
|
||||||
|
#include "td/db/binlog/BinlogInterface.h"
|
||||||
#include "td/db/DbKey.h"
|
#include "td/db/DbKey.h"
|
||||||
#include "td/db/KeyValueSyncInterface.h"
|
#include "td/db/KeyValueSyncInterface.h"
|
||||||
|
|
||||||
|
@ -9,10 +9,13 @@
|
|||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/Td.h"
|
#include "td/telegram/Td.h"
|
||||||
|
|
||||||
|
#include "td/utils/buffer.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/PromiseFuture.h"
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
@ -19,7 +19,7 @@ class FileDbId {
|
|||||||
public:
|
public:
|
||||||
FileDbId() = default;
|
FileDbId() = default;
|
||||||
|
|
||||||
FileDbId(uint64 file_db_id) : id(file_db_id) {
|
explicit FileDbId(uint64 file_db_id) : id(file_db_id) {
|
||||||
}
|
}
|
||||||
template <class T1, typename = std::enable_if_t<std::is_convertible<T1, uint64>::value>>
|
template <class T1, typename = std::enable_if_t<std::is_convertible<T1, uint64>::value>>
|
||||||
FileDbId(T1 file_db_id) = delete;
|
FileDbId(T1 file_db_id) = delete;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "td/telegram/files/FileId.h"
|
#include "td/telegram/files/FileId.h"
|
||||||
|
|
||||||
|
#include "td/telegram/files/FileManager.h"
|
||||||
#include "td/telegram/files/FileManager.hpp"
|
#include "td/telegram/files/FileManager.hpp"
|
||||||
#include "td/telegram/Td.h"
|
#include "td/telegram/Td.h"
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ class FileSourceId {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(const FileSourceId &other) const {
|
||||||
|
return id < other.id;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const FileSourceId &other) const {
|
bool operator==(const FileSourceId &other) const {
|
||||||
return id == other.id;
|
return id == other.id;
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
//
|
//
|
||||||
#include "td/db/binlog/BinlogHelper.h"
|
#include "td/db/binlog/BinlogHelper.h"
|
||||||
#include "td/db/binlog/ConcurrentBinlog.h"
|
#include "td/db/binlog/ConcurrentBinlog.h"
|
||||||
#include "td/db/SqliteConnectionSafe.h"
|
|
||||||
#include "td/db/BinlogKeyValue.h"
|
#include "td/db/BinlogKeyValue.h"
|
||||||
#include "td/db/SeqKeyValue.h"
|
#include "td/db/SeqKeyValue.h"
|
||||||
|
#include "td/db/SqliteConnectionSafe.h"
|
||||||
#include "td/db/SqliteKeyValue.h"
|
#include "td/db/SqliteKeyValue.h"
|
||||||
#include "td/db/SqliteKeyValueSafe.h"
|
#include "td/db/SqliteKeyValueSafe.h"
|
||||||
#include "td/db/TsSeqKeyValue.h"
|
#include "td/db/TsSeqKeyValue.h"
|
||||||
|
@ -4,16 +4,75 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
#include "td/utils/tests.h"
|
|
||||||
#include "td/utils/Random.h"
|
|
||||||
|
|
||||||
#include "td/telegram/SetWithPosition.h"
|
#include "td/telegram/SetWithPosition.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/Random.h"
|
||||||
|
#include "td/utils/tests.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
using namespace td;
|
using namespace td;
|
||||||
|
|
||||||
template <class T, template <class> class Set = SetWithPosition>
|
template <class T>
|
||||||
|
class OldSetWithPosition {
|
||||||
|
public:
|
||||||
|
void add(T value) {
|
||||||
|
auto it = std::find(values_.begin(), values_.end(), value);
|
||||||
|
if (it != values_.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
values_.push_back(value);
|
||||||
|
}
|
||||||
|
void remove(T value) {
|
||||||
|
auto it = std::find(values_.begin(), values_.end(), value);
|
||||||
|
if (it == values_.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t i = it - values_.begin();
|
||||||
|
values_.erase(it);
|
||||||
|
if (pos_ > i) {
|
||||||
|
pos_--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void reset_position() {
|
||||||
|
pos_ = 0;
|
||||||
|
}
|
||||||
|
T next() {
|
||||||
|
CHECK(has_next());
|
||||||
|
return values_[pos_++];
|
||||||
|
}
|
||||||
|
bool has_next() const {
|
||||||
|
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};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, template <class> class SetWithPosition>
|
||||||
class CheckedSetWithPosition {
|
class CheckedSetWithPosition {
|
||||||
public:
|
public:
|
||||||
void add(int x) {
|
void add(int x) {
|
||||||
@ -28,7 +87,7 @@ class CheckedSetWithPosition {
|
|||||||
checked_.erase(x);
|
checked_.erase(x);
|
||||||
not_checked_.erase(x);
|
not_checked_.erase(x);
|
||||||
}
|
}
|
||||||
bool has_next() {
|
bool has_next() const {
|
||||||
auto res = !not_checked_.empty();
|
auto res = !not_checked_.empty();
|
||||||
//LOG(ERROR) << res;
|
//LOG(ERROR) << res;
|
||||||
ASSERT_EQ(res, s_.has_next());
|
ASSERT_EQ(res, s_.has_next());
|
||||||
@ -74,11 +133,11 @@ class CheckedSetWithPosition {
|
|||||||
private:
|
private:
|
||||||
std::set<T> checked_;
|
std::set<T> checked_;
|
||||||
std::set<T> not_checked_;
|
std::set<T> not_checked_;
|
||||||
Set<T> s_;
|
SetWithPosition<T> s_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <template <class> class RawSet>
|
template <template <class> class RawSet>
|
||||||
void test_hands() {
|
static void test_hands() {
|
||||||
using Set = CheckedSetWithPosition<int, RawSet>;
|
using Set = CheckedSetWithPosition<int, RawSet>;
|
||||||
|
|
||||||
Set a;
|
Set a;
|
||||||
@ -94,12 +153,13 @@ void test_hands() {
|
|||||||
a.next();
|
a.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <class> class RawSet>
|
template <template <class> class RawSet>
|
||||||
void test_stress() {
|
static void test_stress() {
|
||||||
Random::Xorshift128plus rnd(123);
|
Random::Xorshift128plus rnd(123);
|
||||||
using Set = CheckedSetWithPosition<int, RawSet>;
|
using Set = CheckedSetWithPosition<int, RawSet>;
|
||||||
for (int t = 0; t < 100; t++) {
|
for (int t = 0; t < 10; t++) {
|
||||||
std::vector<unique_ptr<Set>> sets(1000);
|
std::vector<unique_ptr<Set>> sets(100);
|
||||||
for (auto &s : sets) {
|
for (auto &s : sets) {
|
||||||
s = make_unique<Set>();
|
s = make_unique<Set>();
|
||||||
}
|
}
|
||||||
@ -163,11 +223,12 @@ void test_stress() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <class> class RawSet>
|
template <template <class> class RawSet>
|
||||||
void test_speed() {
|
static void test_speed() {
|
||||||
Random::Xorshift128plus rnd(123);
|
Random::Xorshift128plus rnd(123);
|
||||||
using Set = CheckedSetWithPosition<int, RawSet>;
|
using Set = CheckedSetWithPosition<int, RawSet>;
|
||||||
std::vector<unique_ptr<Set>> sets(1 << 18);
|
std::vector<unique_ptr<Set>> sets(1 << 13);
|
||||||
for (size_t i = 0; i < sets.size(); i++) {
|
for (size_t i = 0; i < sets.size(); i++) {
|
||||||
sets[i] = make_unique<Set>();
|
sets[i] = make_unique<Set>();
|
||||||
sets[i]->add(int(i));
|
sets[i]->add(int(i));
|
||||||
@ -187,11 +248,13 @@ TEST(SetWithPosition, hands) {
|
|||||||
test_hands<OldSetWithPosition>();
|
test_hands<OldSetWithPosition>();
|
||||||
test_hands<SetWithPosition>();
|
test_hands<SetWithPosition>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SetWithPosition, stress) {
|
TEST(SetWithPosition, stress) {
|
||||||
test_stress<FastSetWithPosition>();
|
test_stress<FastSetWithPosition>();
|
||||||
test_stress<OldSetWithPosition>();
|
test_stress<OldSetWithPosition>();
|
||||||
test_stress<SetWithPosition>();
|
test_stress<SetWithPosition>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SetWithPosition, speed) {
|
TEST(SetWithPosition, speed) {
|
||||||
test_speed<FastSetWithPosition>();
|
test_speed<FastSetWithPosition>();
|
||||||
test_speed<SetWithPosition>();
|
test_speed<SetWithPosition>();
|
||||||
|
Reference in New Issue
Block a user