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/Global.h"
|
||||
#include "td/telegram/MessagesManager.h"
|
||||
#include "td/telegram/WallpaperManager.h"
|
||||
#include "td/telegram/WebPagesManager.h"
|
||||
|
||||
#include "td/actor/MultiPromise.h"
|
||||
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "td/utils/Variant.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -9,15 +9,16 @@
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/telegram/ChatId.h"
|
||||
#include "td/telegram/ChannelId.h"
|
||||
#include "td/telegram/ChatId.h"
|
||||
#include "td/telegram/files/FileId.h"
|
||||
#include "td/telegram/files/FileManager.h"
|
||||
#include "td/telegram/files/FileSourceId.h"
|
||||
#include "td/telegram/MessageId.h"
|
||||
#include "td/telegram/SetWithPosition.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Variant.h"
|
||||
|
||||
#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;
|
||||
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_,
|
||||
file_location.local_id_, file_location.secret_,
|
||||
BufferSlice());
|
||||
file_location.local_id_, file_location.secret_, BufferSlice());
|
||||
}
|
||||
|
||||
// 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_)) {
|
||||
from.mime_type_.clear();
|
||||
}
|
||||
return make_tl_object<telegram_api::document>(
|
||||
from.id_, from.access_hash_, BufferSlice(), from.date_, from.mime_type_, from.size_,
|
||||
secret_to_telegram<telegram_api::PhotoSize>(*from.thumb_), from.dc_id_, secret_to_telegram(from.attributes_));
|
||||
return make_tl_object<telegram_api::document>(from.id_, from.access_hash_, BufferSlice(), from.date_, from.mime_type_,
|
||||
from.size_, secret_to_telegram<telegram_api::PhotoSize>(*from.thumb_),
|
||||
from.dc_id_, secret_to_telegram(from.attributes_));
|
||||
}
|
||||
|
||||
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)
|
||||
//
|
||||
#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
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
#include "td/telegram/TdParameters.h"
|
||||
|
||||
#include "td/db/binlog/BinlogInterface.h"
|
||||
#include "td/db/binlog/BinlogEvent.h"
|
||||
#include "td/db/binlog/BinlogInterface.h"
|
||||
#include "td/db/DbKey.h"
|
||||
#include "td/db/KeyValueSyncInterface.h"
|
||||
|
||||
|
@ -9,10 +9,13 @@
|
||||
#include "td/telegram/td_api.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/Global.h"
|
||||
#include "td/telegram/Photo.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "td/telegram/Photo.h"
|
||||
#include "td/telegram/td_api.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
@ -19,7 +19,7 @@ class FileDbId {
|
||||
public:
|
||||
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>>
|
||||
FileDbId(T1 file_db_id) = delete;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "td/telegram/files/FileId.h"
|
||||
|
||||
#include "td/telegram/files/FileManager.h"
|
||||
#include "td/telegram/files/FileManager.hpp"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
|
@ -33,6 +33,10 @@ class FileSourceId {
|
||||
return id;
|
||||
}
|
||||
|
||||
bool operator<(const FileSourceId &other) const {
|
||||
return id < other.id;
|
||||
}
|
||||
|
||||
bool operator==(const FileSourceId &other) const {
|
||||
return id == other.id;
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
//
|
||||
#include "td/db/binlog/BinlogHelper.h"
|
||||
#include "td/db/binlog/ConcurrentBinlog.h"
|
||||
#include "td/db/SqliteConnectionSafe.h"
|
||||
#include "td/db/BinlogKeyValue.h"
|
||||
#include "td/db/SeqKeyValue.h"
|
||||
#include "td/db/SqliteConnectionSafe.h"
|
||||
#include "td/db/SqliteKeyValue.h"
|
||||
#include "td/db/SqliteKeyValueSafe.h"
|
||||
#include "td/db/TsSeqKeyValue.h"
|
||||
|
@ -4,16 +4,75 @@
|
||||
// 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)
|
||||
//
|
||||
#include "td/utils/tests.h"
|
||||
#include "td/utils/Random.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 <utility>
|
||||
|
||||
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 {
|
||||
public:
|
||||
void add(int x) {
|
||||
@ -28,7 +87,7 @@ class CheckedSetWithPosition {
|
||||
checked_.erase(x);
|
||||
not_checked_.erase(x);
|
||||
}
|
||||
bool has_next() {
|
||||
bool has_next() const {
|
||||
auto res = !not_checked_.empty();
|
||||
//LOG(ERROR) << res;
|
||||
ASSERT_EQ(res, s_.has_next());
|
||||
@ -74,11 +133,11 @@ class CheckedSetWithPosition {
|
||||
private:
|
||||
std::set<T> checked_;
|
||||
std::set<T> not_checked_;
|
||||
Set<T> s_;
|
||||
SetWithPosition<T> s_;
|
||||
};
|
||||
|
||||
template <template <class> class RawSet>
|
||||
void test_hands() {
|
||||
static void test_hands() {
|
||||
using Set = CheckedSetWithPosition<int, RawSet>;
|
||||
|
||||
Set a;
|
||||
@ -94,12 +153,13 @@ void test_hands() {
|
||||
a.next();
|
||||
}
|
||||
}
|
||||
|
||||
template <template <class> class RawSet>
|
||||
void test_stress() {
|
||||
static void test_stress() {
|
||||
Random::Xorshift128plus rnd(123);
|
||||
using Set = CheckedSetWithPosition<int, RawSet>;
|
||||
for (int t = 0; t < 100; t++) {
|
||||
std::vector<unique_ptr<Set>> sets(1000);
|
||||
for (int t = 0; t < 10; t++) {
|
||||
std::vector<unique_ptr<Set>> sets(100);
|
||||
for (auto &s : sets) {
|
||||
s = make_unique<Set>();
|
||||
}
|
||||
@ -163,11 +223,12 @@ void test_stress() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <template <class> class RawSet>
|
||||
void test_speed() {
|
||||
static void test_speed() {
|
||||
Random::Xorshift128plus rnd(123);
|
||||
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++) {
|
||||
sets[i] = make_unique<Set>();
|
||||
sets[i]->add(int(i));
|
||||
@ -187,11 +248,13 @@ TEST(SetWithPosition, hands) {
|
||||
test_hands<OldSetWithPosition>();
|
||||
test_hands<SetWithPosition>();
|
||||
}
|
||||
|
||||
TEST(SetWithPosition, stress) {
|
||||
test_stress<FastSetWithPosition>();
|
||||
test_stress<OldSetWithPosition>();
|
||||
test_stress<SetWithPosition>();
|
||||
}
|
||||
|
||||
TEST(SetWithPosition, speed) {
|
||||
test_speed<FastSetWithPosition>();
|
||||
test_speed<SetWithPosition>();
|
||||
|
Reference in New Issue
Block a user