Skip to content

Commit

Permalink
Improvement #7038 - Improve performance of STARTING WITH of fixed-byt…
Browse files Browse the repository at this point in the history
…e charsets with insensitive collations.
  • Loading branch information
asfernandes committed Nov 4, 2021
1 parent 6140244 commit 551ed99
Showing 1 changed file with 27 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/jrd/Collation.cpp
Expand Up @@ -444,15 +444,17 @@ template <typename CharType, typename StrConverter>
class StartsMatcher : public PatternMatcher
{
public:
StartsMatcher(MemoryPool& pool, TextType* ttype, const CharType* str, SLONG str_len)
StartsMatcher(MemoryPool& pool, TextType* ttype, const CharType* str, SLONG str_len, SLONG aPatternByteLength)
: PatternMatcher(pool, ttype),
evaluator(pool, str, str_len)
evaluator(pool, str, str_len),
patternByteLength(ttype->getCharSet()->isMultiByte() ? -1 : aPatternByteLength)
{
}

void reset()
{
evaluator.reset();
processedByteLength = 0;
}

bool result()
Expand All @@ -462,36 +464,57 @@ class StartsMatcher : public PatternMatcher

bool process(const UCHAR* str, SLONG length)
{
if (patternByteLength != -1)
{
if (processedByteLength + length > patternByteLength)
length = patternByteLength - processedByteLength;
}

processedByteLength += length;

StrConverter cvt(pool, textType, str, length);
fb_assert(length % sizeof(CharType) == 0);

return evaluator.processNextChunk(
reinterpret_cast<const CharType*>(str), length / sizeof(CharType));
}

static StartsMatcher* create(MemoryPool& pool, TextType* ttype,
const UCHAR* str, SLONG length)
{
const auto patternByteLength = length;

StrConverter cvt(pool, ttype, str, length);
fb_assert(length % sizeof(CharType) == 0);

return FB_NEW_POOL(pool) StartsMatcher(pool, ttype,
reinterpret_cast<const CharType*>(str), length / sizeof(CharType));
reinterpret_cast<const CharType*>(str), length / sizeof(CharType), patternByteLength);
}

static bool evaluate(MemoryPool& pool, TextType* ttype, const UCHAR* s, SLONG sl,
const UCHAR* p, SLONG pl)
{
if (!ttype->getCharSet()->isMultiByte() && sl > pl)
sl = pl;

StrConverter cvt1(pool, ttype, p, pl);
StrConverter cvt2(pool, ttype, s, sl);
fb_assert(pl % sizeof(CharType) == 0);

StrConverter cvt2(pool, ttype, s, sl);
fb_assert(sl % sizeof(CharType) == 0);

Firebird::StartsEvaluator<CharType> evaluator(pool,
reinterpret_cast<const CharType*>(p), pl / sizeof(CharType));

evaluator.processNextChunk(reinterpret_cast<const CharType*>(s), sl / sizeof(CharType));

return evaluator.getResult();
}

private:
Firebird::StartsEvaluator<CharType> evaluator;
const SLONG patternByteLength; // -1 used for MBCS and not optimize things
SLONG processedByteLength = 0;
};

template <typename CharType, typename StrConverter = CanonicalConverter<UpcaseConverter<> > >
Expand Down

0 comments on commit 551ed99

Please sign in to comment.