mirror of https://github.com/procxx/kepka.git
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>
|
template <typename T>
|
||||||
class HistoryItemInstantiated {
|
class HistoryItemInstantiated {
|
||||||
public:
|
public:
|
||||||
template <typename ... Args>
|
template <typename ...Args>
|
||||||
static T *_create(Args ... args) {
|
static T *_create(Args &&... args) {
|
||||||
T *result = new T(args ...);
|
T *result = new T(std::forward<Args>(args)...);
|
||||||
result->finishCreate();
|
result->finishCreate();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,28 +174,94 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class mtpData {
|
namespace MTP {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class TypeData {
|
||||||
public:
|
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:
|
public:
|
||||||
mtpDataOwner(mtpDataOwner &&other) = default;
|
TypeDataOwner(TypeDataOwner &&other) : _data(base::take(other._data)) {
|
||||||
mtpDataOwner(const mtpDataOwner &other) = default;
|
}
|
||||||
mtpDataOwner &operator=(mtpDataOwner &&other) = default;
|
TypeDataOwner(const TypeDataOwner &other) : _data(other._data) {
|
||||||
mtpDataOwner &operator=(const mtpDataOwner &other) = default;
|
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:
|
protected:
|
||||||
mtpDataOwner() = default;
|
TypeDataOwner() = default;
|
||||||
explicit mtpDataOwner(std::shared_ptr<const mtpData> &&data) : data(data) {
|
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 {
|
enum {
|
||||||
// core types
|
// core types
|
||||||
mtpc_int = 0xa8509bda,
|
mtpc_int = 0xa8509bda,
|
||||||
|
|
|
@ -94,7 +94,7 @@ with open('scheme.tl') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
layerline = re.match(r'// LAYER (\d+)', line)
|
layerline = re.match(r'// LAYER (\d+)', line)
|
||||||
if (layerline):
|
if (layerline):
|
||||||
layer = 'static constexpr mtpPrime CurrentLayer = ' + layerline.group(1) + ';';
|
layer = 'constexpr auto CurrentLayer = mtpPrime(' + layerline.group(1) + ');';
|
||||||
nocomment = re.match(r'^(.*?)//', line)
|
nocomment = re.match(r'^(.*?)//', line)
|
||||||
if (nocomment):
|
if (nocomment):
|
||||||
line = nocomment.group(1);
|
line = nocomment.group(1);
|
||||||
|
@ -571,7 +571,7 @@ for restype in typesList:
|
||||||
trivialConditions = data[7];
|
trivialConditions = data[7];
|
||||||
|
|
||||||
dataText = '';
|
dataText = '';
|
||||||
dataText += '\nclass MTPD' + name + ' : public mtpData {\n'; # data class
|
dataText += '\nclass MTPD' + name + ' : public MTP::internal::TypeData {\n'; # data class
|
||||||
dataText += 'public:\n';
|
dataText += 'public:\n';
|
||||||
|
|
||||||
sizeList = [];
|
sizeList = [];
|
||||||
|
@ -606,20 +606,18 @@ for restype in typesList:
|
||||||
dataText += '\tMTPD' + name + '() = default;\n'; # default constructor
|
dataText += '\tMTPD' + name + '() = default;\n'; # default constructor
|
||||||
switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
|
switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
|
||||||
if (len(prms) > len(trivialConditions)):
|
if (len(prms) > len(trivialConditions)):
|
||||||
switchLines += 'data = std::make_shared<MTPD' + name + '>(); ';
|
switchLines += 'setData(new MTPD' + name + '()); ';
|
||||||
withData = 1;
|
withData = 1;
|
||||||
|
|
||||||
getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
|
getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
|
||||||
constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
|
constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
|
||||||
if (withType):
|
if (withType):
|
||||||
constructsInline += '\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n';
|
constructsInline += '\tt_assert(_type == mtpc_' + name + ');\n';
|
||||||
else:
|
constructsInline += '\treturn queryData<MTPD' + name + '>();\n';
|
||||||
constructsInline += '\tt_assert(data != nullptr);\n';
|
|
||||||
constructsInline += '\treturn static_cast<const MTPD' + name + '&>(*data);\n';
|
|
||||||
constructsInline += '}\n';
|
constructsInline += '}\n';
|
||||||
|
|
||||||
constructsText += '\texplicit MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data);\n'; # by-data type constructor
|
constructsText += '\texplicit MTP' + restype + '(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))';
|
constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(const MTPD' + name + ' *data) : TypeDataOwner(data)';
|
||||||
if (withType):
|
if (withType):
|
||||||
constructsInline += ', _type(mtpc_' + name + ')';
|
constructsInline += ', _type(mtpc_' + name + ')';
|
||||||
constructsInline += ' {\n}\n';
|
constructsInline += ' {\n}\n';
|
||||||
|
@ -667,7 +665,7 @@ for restype in typesList:
|
||||||
sizeCases += '\t\t\treturn ' + ' + '.join(sizeList) + ';\n';
|
sizeCases += '\t\t\treturn ' + ' + '.join(sizeList) + ';\n';
|
||||||
sizeCases += '\t\t}\n';
|
sizeCases += '\t\t}\n';
|
||||||
sizeFast = '\tconst MTPD' + name + ' &v(c_' + name + '());\n\treturn ' + ' + '.join(sizeList) + ';\n';
|
sizeFast = '\tconst MTPD' + name + ' &v(c_' + name + '());\n\treturn ' + ' + '.join(sizeList) + ';\n';
|
||||||
newFast = 'std::make_shared<MTPD' + name + '>()';
|
newFast = 'new MTPD' + name + '()';
|
||||||
else:
|
else:
|
||||||
sizeFast = '\treturn 0;\n';
|
sizeFast = '\treturn 0;\n';
|
||||||
|
|
||||||
|
@ -681,7 +679,7 @@ for restype in typesList:
|
||||||
friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
|
friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
|
||||||
creatorProxyText += '\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
creatorProxyText += '\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
||||||
if (len(prms) > len(trivialConditions)): # creator with params
|
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:
|
else:
|
||||||
if (withType): # creator by type
|
if (withType): # creator by type
|
||||||
creatorProxyText += '\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
|
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
|
reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
|
||||||
if (len(prms) > len(trivialConditions)):
|
if (len(prms) > len(trivialConditions)):
|
||||||
reader += '{\n';
|
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 += readText;
|
||||||
reader += '\t\t\tdata = std::move(v);\n';
|
|
||||||
reader += '\t\t} break;\n';
|
reader += '\t\t} break;\n';
|
||||||
|
|
||||||
writer += '\t\tcase mtpc_' + name + ': {\n'; # write switch line
|
writer += '\t\tcase mtpc_' + name + ': {\n'; # write switch line
|
||||||
|
@ -711,9 +709,9 @@ for restype in typesList:
|
||||||
reader += 'break;\n';
|
reader += 'break;\n';
|
||||||
else:
|
else:
|
||||||
if (len(prms) > len(trivialConditions)):
|
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 += readText;
|
||||||
reader += '\tdata = std::move(v);\n';
|
|
||||||
|
|
||||||
writer += '\tauto &v = c_' + name + '();\n';
|
writer += '\tauto &v = c_' + name + '();\n';
|
||||||
writer += writeText;
|
writer += writeText;
|
||||||
|
@ -722,14 +720,14 @@ for restype in typesList:
|
||||||
|
|
||||||
typesText += '\nclass MTP' + restype; # type class declaration
|
typesText += '\nclass MTP' + restype; # type class declaration
|
||||||
if (withData):
|
if (withData):
|
||||||
typesText += ' : private mtpDataOwner'; # if has data fields
|
typesText += ' : private MTP::internal::TypeDataOwner'; # if has data fields
|
||||||
typesText += ' {\n';
|
typesText += ' {\n';
|
||||||
typesText += 'public:\n';
|
typesText += 'public:\n';
|
||||||
typesText += '\tMTP' + restype + '()'; # default constructor
|
typesText += '\tMTP' + restype + '()'; # default constructor
|
||||||
inits = [];
|
inits = [];
|
||||||
if not (withType):
|
if not (withType):
|
||||||
if (withData):
|
if (withData):
|
||||||
inits.append('mtpDataOwner(' + newFast + ')');
|
inits.append('TypeDataOwner(' + newFast + ')');
|
||||||
if (withData and not withType):
|
if (withData and not withType):
|
||||||
typesText += ';\n';
|
typesText += ';\n';
|
||||||
inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
|
inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
|
||||||
|
@ -770,9 +768,7 @@ for restype in typesList:
|
||||||
typesText += ');\n';
|
typesText += ');\n';
|
||||||
inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
||||||
if (withData):
|
if (withData):
|
||||||
if (withType):
|
if not (withType):
|
||||||
inlineMethods += '\tdata.reset();\n';
|
|
||||||
else:
|
|
||||||
inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||||
if (withType):
|
if (withType):
|
||||||
inlineMethods += '\tswitch (cons) {\n'
|
inlineMethods += '\tswitch (cons) {\n'
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue