Fix build for Xcode.

Also guard database compactor so that it won't work after closing.
This commit is contained in:
John Preston 2018-08-29 22:07:47 +03:00
parent 08ff324b1b
commit 8210a51fdc
8 changed files with 76 additions and 42 deletions

View File

@ -129,7 +129,6 @@ private:
base::binary_guard _running; base::binary_guard _running;
TimeMs _next = 0; TimeMs _next = 0;
int _timeout = 0; int _timeout = 0;
int _timerId = 0;
Qt::TimerType _type : 2; Qt::TimerType _type : 2;
bool _adjusted : 1; bool _adjusted : 1;

View File

@ -22,6 +22,7 @@ public:
CompactorObject( CompactorObject(
crl::weak_on_queue<CompactorObject> weak, crl::weak_on_queue<CompactorObject> weak,
crl::weak_on_queue<DatabaseObject> database, crl::weak_on_queue<DatabaseObject> database,
base::binary_guard guard,
const QString &base, const QString &base,
const Settings &settings, const Settings &settings,
EncryptionKey &&key, EncryptionKey &&key,
@ -64,6 +65,7 @@ private:
crl::weak_on_queue<CompactorObject> _weak; crl::weak_on_queue<CompactorObject> _weak;
crl::weak_on_queue<DatabaseObject> _database; crl::weak_on_queue<DatabaseObject> _database;
base::binary_guard _guard;
QString _base; QString _base;
Settings _settings; Settings _settings;
EncryptionKey _key; EncryptionKey _key;
@ -83,12 +85,14 @@ private:
CompactorObject::CompactorObject( CompactorObject::CompactorObject(
crl::weak_on_queue<CompactorObject> weak, crl::weak_on_queue<CompactorObject> weak,
crl::weak_on_queue<DatabaseObject> database, crl::weak_on_queue<DatabaseObject> database,
base::binary_guard guard,
const QString &base, const QString &base,
const Settings &settings, const Settings &settings,
EncryptionKey &&key, EncryptionKey &&key,
const Info &info) const Info &info)
: _weak(std::move(weak)) : _weak(std::move(weak))
, _database(std::move(database)) , _database(std::move(database))
, _guard(std::move(guard))
, _base(base) , _base(base)
, _settings(settings) , _settings(settings)
, _key(std::move(key)) , _key(std::move(key))
@ -170,8 +174,10 @@ void CompactorObject::fail() {
void CompactorObject::done(int64 till) { void CompactorObject::done(int64 till) {
const auto path = compactPath(); const auto path = compactPath();
_database.with([=](DatabaseObject &database) { _database.with([=, good = std::move(_guard)](DatabaseObject &database) {
database.compactorDone(path, till); if (good.alive()) {
database.compactorDone(path, till);
}
}); });
} }
@ -354,7 +360,7 @@ void CompactorObject::addListRecord(
} }
auto record = RecordStore(); auto record = RecordStore();
record.key = raw.first; record.key = raw.first;
record.size = ReadTo<EntrySize>(raw.second.size); record.setSize(raw.second.size);
record.checksum = raw.second.checksum; record.checksum = raw.second.checksum;
record.tag = raw.second.tag; record.tag = raw.second.tag;
record.place = raw.second.place; record.place = raw.second.place;
@ -367,11 +373,18 @@ void CompactorObject::addListRecord(
Compactor::Compactor( Compactor::Compactor(
crl::weak_on_queue<DatabaseObject> database, crl::weak_on_queue<DatabaseObject> database,
base::binary_guard guard,
const QString &base, const QString &base,
const Settings &settings, const Settings &settings,
EncryptionKey &&key, EncryptionKey &&key,
const Info &info) const Info &info)
: _wrapped(std::move(database), base, settings, std::move(key), info) { : _wrapped(
std::move(database),
std::move(guard),
base,
settings,
std::move(key),
info) {
} }
Compactor::~Compactor() = default; Compactor::~Compactor() = default;

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/cache/storage_cache_types.h" #include "storage/cache/storage_cache_types.h"
#include <crl/crl_object_on_queue.h> #include <crl/crl_object_on_queue.h>
#include <base/binary_guard.h>
namespace Storage { namespace Storage {
class EncryptionKey; class EncryptionKey;
@ -28,6 +29,7 @@ public:
Compactor( Compactor(
crl::weak_on_queue<DatabaseObject> database, crl::weak_on_queue<DatabaseObject> database,
base::binary_guard guard,
const QString &base, const QString &base,
const Settings &settings, const Settings &settings,
EncryptionKey &&key, EncryptionKey &&key,

View File

@ -69,8 +69,8 @@ DatabaseObject::Entry::Entry(
: useTime(useTime) : useTime(useTime)
, size(size) , size(size)
, checksum(checksum) , checksum(checksum)
, tag(tag) , place(place)
, place(place) { , tag(tag) {
} }
DatabaseObject::DatabaseObject( DatabaseObject::DatabaseObject(
@ -488,7 +488,7 @@ template <typename Record, typename Postprocess>
bool DatabaseObject::processRecordStoreGeneric( bool DatabaseObject::processRecordStoreGeneric(
const Record *record, const Record *record,
Postprocess &&postprocess) { Postprocess &&postprocess) {
const auto size = ReadFrom(record->size); const auto size = record->getSize();
if (size <= 0 || size > _settings.maxDataSize) { if (size <= 0 || size > _settings.maxDataSize) {
return false; return false;
} }
@ -738,6 +738,7 @@ void DatabaseObject::clearState() {
_map = {}; _map = {};
_removing = {}; _removing = {};
_accessed = {}; _accessed = {};
_stale = {};
_time = {}; _time = {};
_binlogExcessLength = 0; _binlogExcessLength = 0;
_totalSize = 0; _totalSize = 0;
@ -747,7 +748,6 @@ void DatabaseObject::clearState() {
_pushingStats = false; _pushingStats = false;
_writeBundlesTimer.cancel(); _writeBundlesTimer.cancel();
_pruneTimer.cancel(); _pruneTimer.cancel();
_cleaner = CleanerWrap();
_compactor = CompactorWrap(); _compactor = CompactorWrap();
} }
@ -816,7 +816,7 @@ base::optional<QString> DatabaseObject::writeKeyPlaceGeneric(
const auto size = size_type(value.bytes.size()); const auto size = size_type(value.bytes.size());
record.tag = value.tag; record.tag = value.tag;
record.key = key; record.key = key;
record.size = ReadTo<EntrySize>(size); record.setSize(size);
record.checksum = checksum; record.checksum = checksum;
if (const auto i = _map.find(key); i != end(_map)) { if (const auto i = _map.find(key); i != end(_map)) {
const auto &already = i->second; const auto &already = i->second;
@ -876,7 +876,7 @@ Error DatabaseObject::writeExistingPlaceGeneric(
const Entry &entry) { const Entry &entry) {
record.key = key; record.key = key;
record.tag = entry.tag; record.tag = entry.tag;
record.size = ReadTo<EntrySize>(entry.size); record.setSize(entry.size);
record.checksum = entry.checksum; record.checksum = entry.checksum;
if (const auto i = _map.find(key); i != end(_map)) { if (const auto i = _map.find(key); i != end(_map)) {
const auto &already = i->second; const auto &already = i->second;
@ -1187,8 +1187,11 @@ void DatabaseObject::checkCompactor() {
info.till = _binlog.size(); info.till = _binlog.size();
info.systemTime = _time.system; info.systemTime = _time.system;
info.keysCount = _map.size(); info.keysCount = _map.size();
auto [first, second] = base::make_binary_guard();
_compactor.guard = std::move(first);
_compactor.object = std::make_unique<Compactor>( _compactor.object = std::make_unique<Compactor>(
_weak, _weak,
std::move(second),
_path, _path,
_settings, _settings,
base::duplicate(_key), base::duplicate(_key),

View File

@ -96,6 +96,7 @@ private:
int64 excessLength = 0; int64 excessLength = 0;
crl::time_type nextAttempt = 0; crl::time_type nextAttempt = 0;
crl::time_type delayAfterFailure = 10 * crl::time_type(1000); crl::time_type delayAfterFailure = 10 * crl::time_type(1000);
base::binary_guard guard;
}; };
using Map = std::unordered_map<Key, Entry>; using Map = std::unordered_map<Key, Entry>;

View File

@ -12,6 +12,37 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Storage { namespace Storage {
namespace Cache { namespace Cache {
namespace details { namespace details {
namespace {
template <typename Packed>
inline Packed ReadTo(size_type count) {
Expects(count >= 0 && count < (1 << (Packed().size() * 8)));
auto result = Packed();
for (auto &element : result) {
element = uint8(count & 0xFF);
count >>= 8;
}
return result;
}
template <typename Packed>
inline size_type ReadFrom(const Packed &count) {
auto result = size_type();
for (auto &element : (count | ranges::view::reverse)) {
result <<= 8;
result |= size_type(element);
}
return result;
}
template <typename Packed>
inline size_type ValidateStrictCount(const Packed &count) {
const auto result = ReadFrom(count);
return (result != 0) ? result : -1;
}
} // namespace
TaggedValue::TaggedValue(QByteArray &&bytes, uint8 tag) TaggedValue::TaggedValue(QByteArray &&bytes, uint8 tag)
: bytes(std::move(bytes)), tag(tag) { : bytes(std::move(bytes)), tag(tag) {
@ -61,6 +92,14 @@ BasicHeader::BasicHeader()
, flags(0) { , flags(0) {
} }
void Store::setSize(size_type size) {
this->size = ReadTo<EntrySize>(size);
}
size_type Store::getSize() const {
return ReadFrom(size);
}
MultiStore::MultiStore(size_type count) MultiStore::MultiStore(size_type count)
: type(kType) : type(kType)
, count(ReadTo<RecordsCount>(count)) { , count(ReadTo<RecordsCount>(count)) {

View File

@ -101,34 +101,6 @@ using PlaceId = std::array<uint8, 7>;
using EntrySize = std::array<uint8, 3>; using EntrySize = std::array<uint8, 3>;
using RecordsCount = std::array<uint8, 3>; using RecordsCount = std::array<uint8, 3>;
template <typename Packed>
inline Packed ReadTo(size_type count) {
Expects(count >= 0 && count < (1 << (Packed().size() * 8)));
auto result = Packed();
for (auto &element : result) {
element = uint8(count & 0xFF);
count >>= 8;
}
return result;
}
template <typename Packed>
inline size_type ReadFrom(const Packed &count) {
auto result = size_type();
for (auto &element : (count | ranges::view::reverse)) {
result <<= 8;
result |= size_type(element);
}
return result;
}
template <typename Packed>
inline size_type ValidateStrictCount(const Packed &count) {
const auto result = ReadFrom(count);
return (result != 0) ? result : -1;
}
constexpr auto kRecordSizeUnknown = size_type(-1); constexpr auto kRecordSizeUnknown = size_type(-1);
constexpr auto kRecordSizeInvalid = size_type(-2); constexpr auto kRecordSizeInvalid = size_type(-2);
constexpr auto kBundledRecordsLimit = (1 << (RecordsCount().size() * 8)); constexpr auto kBundledRecordsLimit = (1 << (RecordsCount().size() * 8));
@ -170,6 +142,9 @@ struct EstimatedTimePoint {
struct Store { struct Store {
static constexpr auto kType = RecordType(0x01); static constexpr auto kType = RecordType(0x01);
void setSize(size_type size);
size_type getSize() const;
RecordType type = kType; RecordType type = kType;
uint8 tag = 0; uint8 tag = 0;
EntrySize size = { { 0 } }; EntrySize size = { { 0 } };

View File

@ -14,8 +14,8 @@ namespace Storage {
DatabasePointer::DatabasePointer( DatabasePointer::DatabasePointer(
not_null<Databases*> owner, not_null<Databases*> owner,
const std::unique_ptr<Cache::Database> &value) const std::unique_ptr<Cache::Database> &value)
: _owner(owner) : _value(value.get())
, _value(value.get()) { , _owner(owner) {
} }
DatabasePointer::DatabasePointer(DatabasePointer &&other) DatabasePointer::DatabasePointer(DatabasePointer &&other)
@ -83,7 +83,9 @@ DatabasePointer Databases::get(
} }
void Databases::destroy(Cache::Database *database) { void Databases::destroy(Cache::Database *database) {
for (auto &[path, kept] : _map) { for (auto &entry : _map) {
const auto &path = entry.first; // Need to capture it in lambda.
auto &kept = entry.second;
if (kept.database.get() == database) { if (kept.database.get() == database) {
Assert(!kept.destroying.alive()); Assert(!kept.destroying.alive());
auto [first, second] = base::make_binary_guard(); auto [first, second] = base::make_binary_guard();