mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 00:08:02 +00:00
Alpha 1.0.21: Use custom refcount for MTP types.
It seems that heavy using std::shared_ptr and std::make_shared like it was before completely kills the compilation time. Also HistoryItem::_create now uses perfect forwarding.
This commit is contained in:
parent
f2cd364e14
commit
bc254228c9
@ -967,9 +967,9 @@ protected:
|
||||
template <typename T>
|
||||
class HistoryItemInstantiated {
|
||||
public:
|
||||
template <typename ... Args>
|
||||
static T *_create(Args ... args) {
|
||||
T *result = new T(args ...);
|
||||
template <typename ...Args>
|
||||
static T *_create(Args &&... args) {
|
||||
T *result = new T(std::forward<Args>(args)...);
|
||||
result->finishCreate();
|
||||
return result;
|
||||
}
|
||||
|
@ -174,28 +174,94 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class mtpData {
|
||||
namespace MTP {
|
||||
namespace internal {
|
||||
|
||||
class TypeData {
|
||||
public:
|
||||
virtual ~mtpData() {
|
||||
TypeData() = default;
|
||||
TypeData(const TypeData &other) = delete;
|
||||
TypeData(TypeData &&other) = delete;
|
||||
TypeData &operator=(const TypeData &other) = delete;
|
||||
TypeData &operator=(TypeData &&other) = delete;
|
||||
|
||||
void incrementCounter() const {
|
||||
_counter.ref();
|
||||
}
|
||||
|
||||
bool decrementCounter() const {
|
||||
return _counter.deref();
|
||||
}
|
||||
|
||||
virtual ~TypeData() {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable QAtomicInt _counter = { 1 };
|
||||
|
||||
};
|
||||
|
||||
class mtpDataOwner {
|
||||
class TypeDataOwner {
|
||||
public:
|
||||
mtpDataOwner(mtpDataOwner &&other) = default;
|
||||
mtpDataOwner(const mtpDataOwner &other) = default;
|
||||
mtpDataOwner &operator=(mtpDataOwner &&other) = default;
|
||||
mtpDataOwner &operator=(const mtpDataOwner &other) = default;
|
||||
TypeDataOwner(TypeDataOwner &&other) : _data(base::take(other._data)) {
|
||||
}
|
||||
TypeDataOwner(const TypeDataOwner &other) : _data(other._data) {
|
||||
incrementCounter();
|
||||
}
|
||||
TypeDataOwner &operator=(TypeDataOwner &&other) {
|
||||
if (other._data != _data) {
|
||||
decrementCounter();
|
||||
_data = base::take(other._data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
TypeDataOwner &operator=(const TypeDataOwner &other) {
|
||||
if (other._data != _data) {
|
||||
setData(other._data);
|
||||
incrementCounter();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~TypeDataOwner() {
|
||||
decrementCounter();
|
||||
}
|
||||
|
||||
protected:
|
||||
mtpDataOwner() = default;
|
||||
explicit mtpDataOwner(std::shared_ptr<const mtpData> &&data) : data(data) {
|
||||
TypeDataOwner() = default;
|
||||
TypeDataOwner(const TypeData *data) : _data(data) {
|
||||
}
|
||||
std::shared_ptr<const mtpData> data;
|
||||
|
||||
void setData(const TypeData *data) {
|
||||
decrementCounter();
|
||||
_data = data;
|
||||
}
|
||||
|
||||
template <typename DataType>
|
||||
const DataType &queryData() const {
|
||||
// Unsafe cast, type should be checked by the caller.
|
||||
t_assert(_data != nullptr);
|
||||
return static_cast<const DataType &>(*_data);
|
||||
}
|
||||
|
||||
private:
|
||||
void incrementCounter() {
|
||||
if (_data) {
|
||||
_data->incrementCounter();
|
||||
}
|
||||
}
|
||||
void decrementCounter() {
|
||||
if (_data && !_data->decrementCounter()) {
|
||||
delete base::take(_data);
|
||||
}
|
||||
}
|
||||
|
||||
const TypeData * _data = nullptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace MTP
|
||||
|
||||
enum {
|
||||
// core types
|
||||
mtpc_int = 0xa8509bda,
|
||||
|
@ -94,7 +94,7 @@ with open('scheme.tl') as f:
|
||||
for line in f:
|
||||
layerline = re.match(r'// LAYER (\d+)', line)
|
||||
if (layerline):
|
||||
layer = 'static constexpr mtpPrime CurrentLayer = ' + layerline.group(1) + ';';
|
||||
layer = 'constexpr auto CurrentLayer = mtpPrime(' + layerline.group(1) + ');';
|
||||
nocomment = re.match(r'^(.*?)//', line)
|
||||
if (nocomment):
|
||||
line = nocomment.group(1);
|
||||
@ -571,7 +571,7 @@ for restype in typesList:
|
||||
trivialConditions = data[7];
|
||||
|
||||
dataText = '';
|
||||
dataText += '\nclass MTPD' + name + ' : public mtpData {\n'; # data class
|
||||
dataText += '\nclass MTPD' + name + ' : public MTP::internal::TypeData {\n'; # data class
|
||||
dataText += 'public:\n';
|
||||
|
||||
sizeList = [];
|
||||
@ -606,20 +606,18 @@ for restype in typesList:
|
||||
dataText += '\tMTPD' + name + '() = default;\n'; # default constructor
|
||||
switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
|
||||
if (len(prms) > len(trivialConditions)):
|
||||
switchLines += 'data = std::make_shared<MTPD' + name + '>(); ';
|
||||
switchLines += 'setData(new MTPD' + name + '()); ';
|
||||
withData = 1;
|
||||
|
||||
getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
|
||||
constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
|
||||
if (withType):
|
||||
constructsInline += '\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n';
|
||||
else:
|
||||
constructsInline += '\tt_assert(data != nullptr);\n';
|
||||
constructsInline += '\treturn static_cast<const MTPD' + name + '&>(*data);\n';
|
||||
constructsInline += '\tt_assert(_type == mtpc_' + name + ');\n';
|
||||
constructsInline += '\treturn queryData<MTPD' + name + '>();\n';
|
||||
constructsInline += '}\n';
|
||||
|
||||
constructsText += '\texplicit MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data);\n'; # by-data type constructor
|
||||
constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data) : mtpDataOwner(std::move(data))';
|
||||
constructsText += '\texplicit MTP' + restype + '(const MTPD' + name + ' *data);\n'; # by-data type constructor
|
||||
constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(const MTPD' + name + ' *data) : TypeDataOwner(data)';
|
||||
if (withType):
|
||||
constructsInline += ', _type(mtpc_' + name + ')';
|
||||
constructsInline += ' {\n}\n';
|
||||
@ -667,7 +665,7 @@ for restype in typesList:
|
||||
sizeCases += '\t\t\treturn ' + ' + '.join(sizeList) + ';\n';
|
||||
sizeCases += '\t\t}\n';
|
||||
sizeFast = '\tconst MTPD' + name + ' &v(c_' + name + '());\n\treturn ' + ' + '.join(sizeList) + ';\n';
|
||||
newFast = 'std::make_shared<MTPD' + name + '>()';
|
||||
newFast = 'new MTPD' + name + '()';
|
||||
else:
|
||||
sizeFast = '\treturn 0;\n';
|
||||
|
||||
@ -681,7 +679,7 @@ for restype in typesList:
|
||||
friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
|
||||
creatorProxyText += '\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
||||
if (len(prms) > len(trivialConditions)): # creator with params
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '(std::make_shared<MTPD' + name + '>(' + ', '.join(creatorParamsList) + '));\n';
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '(new MTPD' + name + '(' + ', '.join(creatorParamsList) + '));\n';
|
||||
else:
|
||||
if (withType): # creator by type
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
|
||||
@ -698,9 +696,9 @@ for restype in typesList:
|
||||
reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
|
||||
if (len(prms) > len(trivialConditions)):
|
||||
reader += '{\n';
|
||||
reader += '\t\t\tauto v = std::make_shared<MTPD' + name + '>();\n';
|
||||
reader += '\t\t\tauto v = new MTPD' + name + '();\n';
|
||||
reader += '\t\t\tsetData(v);\n';
|
||||
reader += readText;
|
||||
reader += '\t\t\tdata = std::move(v);\n';
|
||||
reader += '\t\t} break;\n';
|
||||
|
||||
writer += '\t\tcase mtpc_' + name + ': {\n'; # write switch line
|
||||
@ -711,9 +709,9 @@ for restype in typesList:
|
||||
reader += 'break;\n';
|
||||
else:
|
||||
if (len(prms) > len(trivialConditions)):
|
||||
reader += '\n\tauto v = std::make_shared<MTPD' + name + '>();\n';
|
||||
reader += '\n\tauto v = new MTPD' + name + '();\n';
|
||||
reader += '\tsetData(v);\n';
|
||||
reader += readText;
|
||||
reader += '\tdata = std::move(v);\n';
|
||||
|
||||
writer += '\tauto &v = c_' + name + '();\n';
|
||||
writer += writeText;
|
||||
@ -722,14 +720,14 @@ for restype in typesList:
|
||||
|
||||
typesText += '\nclass MTP' + restype; # type class declaration
|
||||
if (withData):
|
||||
typesText += ' : private mtpDataOwner'; # if has data fields
|
||||
typesText += ' : private MTP::internal::TypeDataOwner'; # if has data fields
|
||||
typesText += ' {\n';
|
||||
typesText += 'public:\n';
|
||||
typesText += '\tMTP' + restype + '()'; # default constructor
|
||||
inits = [];
|
||||
if not (withType):
|
||||
if (withData):
|
||||
inits.append('mtpDataOwner(' + newFast + ')');
|
||||
inits.append('TypeDataOwner(' + newFast + ')');
|
||||
if (withData and not withType):
|
||||
typesText += ';\n';
|
||||
inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
|
||||
@ -770,9 +768,7 @@ for restype in typesList:
|
||||
typesText += ');\n';
|
||||
inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
||||
if (withData):
|
||||
if (withType):
|
||||
inlineMethods += '\tdata.reset();\n';
|
||||
else:
|
||||
if not (withType):
|
||||
inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||
if (withType):
|
||||
inlineMethods += '\tswitch (cons) {\n'
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user