8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:43:03 +01:00

Improvement #7038 - Improve performance of STARTING WITH of fixed-byte charsets with insensitive collations.

This commit is contained in:
Adriano dos Santos Fernandes 2021-11-04 16:26:22 -03:00
parent 6140244780
commit 551ed996ae

View File

@ -444,15 +444,17 @@ template <typename CharType, typename StrConverter>
class StartsMatcher : public PatternMatcher class StartsMatcher : public PatternMatcher
{ {
public: 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), : PatternMatcher(pool, ttype),
evaluator(pool, str, str_len) evaluator(pool, str, str_len),
patternByteLength(ttype->getCharSet()->isMultiByte() ? -1 : aPatternByteLength)
{ {
} }
void reset() void reset()
{ {
evaluator.reset(); evaluator.reset();
processedByteLength = 0;
} }
bool result() bool result()
@ -462,8 +464,17 @@ public:
bool process(const UCHAR* str, SLONG length) 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); StrConverter cvt(pool, textType, str, length);
fb_assert(length % sizeof(CharType) == 0); fb_assert(length % sizeof(CharType) == 0);
return evaluator.processNextChunk( return evaluator.processNextChunk(
reinterpret_cast<const CharType*>(str), length / sizeof(CharType)); reinterpret_cast<const CharType*>(str), length / sizeof(CharType));
} }
@ -471,27 +482,39 @@ public:
static StartsMatcher* create(MemoryPool& pool, TextType* ttype, static StartsMatcher* create(MemoryPool& pool, TextType* ttype,
const UCHAR* str, SLONG length) const UCHAR* str, SLONG length)
{ {
const auto patternByteLength = length;
StrConverter cvt(pool, ttype, str, length); StrConverter cvt(pool, ttype, str, length);
fb_assert(length % sizeof(CharType) == 0); fb_assert(length % sizeof(CharType) == 0);
return FB_NEW_POOL(pool) StartsMatcher(pool, ttype, 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, static bool evaluate(MemoryPool& pool, TextType* ttype, const UCHAR* s, SLONG sl,
const UCHAR* p, SLONG pl) const UCHAR* p, SLONG pl)
{ {
if (!ttype->getCharSet()->isMultiByte() && sl > pl)
sl = pl;
StrConverter cvt1(pool, ttype, p, pl); StrConverter cvt1(pool, ttype, p, pl);
StrConverter cvt2(pool, ttype, s, sl);
fb_assert(pl % sizeof(CharType) == 0); fb_assert(pl % sizeof(CharType) == 0);
StrConverter cvt2(pool, ttype, s, sl);
fb_assert(sl % sizeof(CharType) == 0); fb_assert(sl % sizeof(CharType) == 0);
Firebird::StartsEvaluator<CharType> evaluator(pool, Firebird::StartsEvaluator<CharType> evaluator(pool,
reinterpret_cast<const CharType*>(p), pl / sizeof(CharType)); reinterpret_cast<const CharType*>(p), pl / sizeof(CharType));
evaluator.processNextChunk(reinterpret_cast<const CharType*>(s), sl / sizeof(CharType)); evaluator.processNextChunk(reinterpret_cast<const CharType*>(s), sl / sizeof(CharType));
return evaluator.getResult(); return evaluator.getResult();
} }
private: private:
Firebird::StartsEvaluator<CharType> evaluator; 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<> > > template <typename CharType, typename StrConverter = CanonicalConverter<UpcaseConverter<> > >