Optimize markdown parser, use less regex matches.

This commit is contained in:
John Preston 2017-07-06 19:57:19 +03:00
parent 8d43bdb084
commit 28f7dc73a5
1 changed files with 24 additions and 9 deletions

View File

@ -1544,6 +1544,9 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(const EntitiesInText &entities, Conver
} }
struct MarkdownPart { struct MarkdownPart {
MarkdownPart() = default;
MarkdownPart(EntityInTextType type) : type(type), outerStart(-1) {
}
EntityInTextType type = EntityInTextInvalid; EntityInTextType type = EntityInTextInvalid;
int outerStart = 0; int outerStart = 0;
int innerStart = 0; int innerStart = 0;
@ -1647,6 +1650,13 @@ void ParseMarkdown(TextWithEntities &result, bool rich) {
} }
auto newResult = TextWithEntities(); auto newResult = TextWithEntities();
MarkdownPart computedParts[4] = {
{ EntityInTextBold },
{ EntityInTextItalic },
{ EntityInTextPre },
{ EntityInTextCode },
};
auto existingEntityIndex = 0; auto existingEntityIndex = 0;
auto existingEntitiesCount = result.entities.size(); auto existingEntitiesCount = result.entities.size();
auto existingEntityShiftLeft = 0; auto existingEntityShiftLeft = 0;
@ -1673,18 +1683,23 @@ void ParseMarkdown(TextWithEntities &result, bool rich) {
} }
} }
auto part = MarkdownPart(); auto part = MarkdownPart();
auto testPart = [&part, &result, matchFromOffset, rich](EntityInTextType type) { auto checkType = [&part, &result, matchFromOffset, rich](MarkdownPart &computedPart) {
auto test = GetMarkdownPart(type, result.text, matchFromOffset, rich); if (computedPart.type == EntityInTextInvalid) {
if (test.type != EntityInTextInvalid) { return;
if (part.type == EntityInTextInvalid || part.outerStart > test.outerStart) {
part = test;
} }
if (matchFromOffset > computedPart.outerStart) {
computedPart = GetMarkdownPart(computedPart.type, result.text, matchFromOffset, rich);
if (computedPart.type == EntityInTextInvalid) {
return;
}
}
if (part.type == EntityInTextInvalid || part.outerStart > computedPart.outerStart) {
part = computedPart;
} }
}; };
testPart(EntityInTextBold); for (auto &computedPart : computedParts) {
testPart(EntityInTextItalic); checkType(computedPart);
testPart(EntityInTextPre); }
testPart(EntityInTextCode);
if (part.type == EntityInTextInvalid) { if (part.type == EntityInTextInvalid) {
break; break;
} }