Minor optimizations to TrxBoundaryParser

This commit is contained in:
Johan Wikman
2017-03-15 10:20:35 +02:00
parent 96f0321b7e
commit c51cd8858d

View File

@ -542,12 +542,23 @@ private:
return type_mask; return type_mask;
} }
inline bool is_next_alpha(char uc, int offset = 1) const
{
ss_dassert(uc >= 'A' && uc <= 'Z');
char lc = uc + ('a' - 'A');
return
((m_pI + offset) < m_pEnd) &&
((*(m_pI + offset) == uc) || (*(m_pI + offset) == lc));
}
bool is_next_char(char c, int offset = 1) const bool is_next_char(char c, int offset = 1) const
{ {
return ((m_pI + offset) < m_pEnd) && (*(m_pI + offset) == c); return ((m_pI + offset) < m_pEnd) && (*(m_pI + offset) == c);
} }
bool get_next_char(char* pC) const bool peek_next_char(char* pC) const
{ {
bool rc = (m_pI + 1 < m_pEnd); bool rc = (m_pI + 1 < m_pEnd);
@ -559,20 +570,28 @@ private:
return rc; return rc;
} }
token_t expect_token(const char* zWord, int len, token_t token) // Significantly faster than library version.
static char toupper(char c)
{ {
const char* pNext = m_pI; return (c >= 'a' && c <='z') ? c - ('a' - 'A') : c;
while ((pNext < m_pEnd) && (isalpha(*pNext) || (*pNext == '@')))
{
++pNext;
} }
if (pNext - m_pI == len) token_t expect_token(const char* zWord, int len, token_t token)
{ {
if (strncasecmp(m_pI, zWord, len) == 0) const char* pI = m_pI;
const char* pEnd = zWord + len;
while ((pI < m_pEnd) && (zWord < pEnd) && (toupper(*pI) == *zWord))
{ {
m_pI = pNext; ++pI;
++zWord;
}
if (zWord == pEnd)
{
if ((pI == m_pEnd) || (!isalpha(*pI))) // Handwritten isalpha not faster than library version.
{
m_pI = pI;
} }
else else
{ {
@ -723,28 +742,28 @@ private:
switch (*m_pI) switch (*m_pI)
{ {
case '@': case '@':
if (is_next_char('a', 2) || is_next_char('A', 2)) if (is_next_alpha('A', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("@@autocommit"), TK_AUTOCOMMIT); token = expect_token(TBP_EXPECT_TOKEN("@@AUTOCOMMIT"), TK_AUTOCOMMIT);
} }
if (is_next_char('s', 2) || is_next_char('S', 2)) else if (is_next_alpha('S', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("@@session"), TK_SESSION_VAR); token = expect_token(TBP_EXPECT_TOKEN("@@SESSION"), TK_SESSION_VAR);
} }
else if (is_next_char('g', 2) || is_next_char('G', 2)) else if (is_next_alpha('G', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("@@global"), TK_GLOBAL_VAR); token = expect_token(TBP_EXPECT_TOKEN("@@GLOBAL"), TK_GLOBAL_VAR);
} }
break; break;
case 'a': case 'a':
case 'A': case 'A':
token = expect_token(TBP_EXPECT_TOKEN("autocommit"), TK_AUTOCOMMIT); token = expect_token(TBP_EXPECT_TOKEN("AUTOCOMMIT"), TK_AUTOCOMMIT);
break; break;
case 'b': case 'b':
case 'B': case 'B':
token = expect_token(TBP_EXPECT_TOKEN("begin"), TK_BEGIN); token = expect_token(TBP_EXPECT_TOKEN("BEGIN"), TK_BEGIN);
break; break;
case ',': case ',':
@ -754,15 +773,15 @@ private:
case 'c': case 'c':
case 'C': case 'C':
if (is_next_char('o') || is_next_char('O')) if (is_next_alpha('O'))
{ {
if (is_next_char('m', 2) || is_next_char('M', 2)) if (is_next_alpha('M', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("commit"), TK_COMMIT); token = expect_token(TBP_EXPECT_TOKEN("COMMIT"), TK_COMMIT);
} }
else if (is_next_char('n', 2) || is_next_char('N', 2)) else if (is_next_alpha('N', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("consistent"), TK_CONSISTENT); token = expect_token(TBP_EXPECT_TOKEN("CONSISTENT"), TK_CONSISTENT);
} }
} }
break; break;
@ -779,18 +798,18 @@ private:
case 'f': case 'f':
case 'F': case 'F':
token = expect_token(TBP_EXPECT_TOKEN("false"), TK_FALSE); token = expect_token(TBP_EXPECT_TOKEN("FALSE"), TK_FALSE);
break; break;
case 'g': case 'g':
case 'G': case 'G':
token = expect_token(TBP_EXPECT_TOKEN("global"), TK_GLOBAL); token = expect_token(TBP_EXPECT_TOKEN("GLOBAL"), TK_GLOBAL);
break; break;
case '1': case '1':
{ {
char c; char c;
if (!get_next_char(&c) || !isdigit(c)) if (!peek_next_char(&c) || !isdigit(c))
{ {
++m_pI; ++m_pI;
token = TK_ONE; token = TK_ONE;
@ -800,93 +819,93 @@ private:
case 'o': case 'o':
case 'O': case 'O':
if (is_next_char('f') || is_next_char('F')) if (is_next_alpha('F'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("off"), TK_ZERO); token = expect_token(TBP_EXPECT_TOKEN("OFF"), TK_ZERO);
} }
else if (is_next_char('n') || is_next_char('N')) else if (is_next_alpha('N'))
{ {
if (is_next_char('l', 2) || is_next_char('L', 2)) if (is_next_char('L', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("only"), TK_ONLY); token = expect_token(TBP_EXPECT_TOKEN("ONLY"), TK_ONLY);
} }
else else
{ {
token = expect_token(TBP_EXPECT_TOKEN("on"), TK_ONE); token = expect_token(TBP_EXPECT_TOKEN("ON"), TK_ONE);
} }
} }
break; break;
case 'r': case 'r':
case 'R': case 'R':
if (is_next_char('e') || is_next_char('E')) if (is_next_alpha('E'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("read"), TK_READ); token = expect_token(TBP_EXPECT_TOKEN("READ"), TK_READ);
} }
else if (is_next_char('o') || is_next_char('O')) else if (is_next_alpha('O'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("rollback"), TK_ROLLBACK); token = expect_token(TBP_EXPECT_TOKEN("ROLLBACK"), TK_ROLLBACK);
} }
break; break;
case 's': case 's':
case 'S': case 'S':
if (is_next_char('e') || is_next_char('E')) if (is_next_alpha('E'))
{ {
if (is_next_char('s', 2) || is_next_char('S', 2)) if (is_next_alpha('S', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("session"), TK_SESSION); token = expect_token(TBP_EXPECT_TOKEN("SESSION"), TK_SESSION);
} }
else else
{ {
token = expect_token(TBP_EXPECT_TOKEN("set"), TK_SET); token = expect_token(TBP_EXPECT_TOKEN("SET"), TK_SET);
} }
} }
else if (is_next_char('n') || is_next_char('N')) else if (is_next_alpha('N'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("snapshot"), TK_SNAPSHOT); token = expect_token(TBP_EXPECT_TOKEN("SNAPSHOT"), TK_SNAPSHOT);
} }
else if (is_next_char('t') || is_next_char('T')) else if (is_next_char('T'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("start"), TK_START); token = expect_token(TBP_EXPECT_TOKEN("START"), TK_START);
} }
break; break;
case 't': case 't':
case 'T': case 'T':
if (is_next_char('r') || is_next_char('R')) if (is_next_alpha('R'))
{ {
if (is_next_char('a', 2) || is_next_char('A', 2)) if (is_next_alpha('A', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("transaction"), TK_TRANSACTION); token = expect_token(TBP_EXPECT_TOKEN("TRANSACTION"), TK_TRANSACTION);
} }
else if (is_next_char('u', 2) || is_next_char('U', 2)) else if (is_next_alpha('U', 2))
{ {
token = expect_token(TBP_EXPECT_TOKEN("true"), TK_TRUE); token = expect_token(TBP_EXPECT_TOKEN("TRUE"), TK_TRUE);
} }
} }
break; break;
case 'w': case 'w':
case 'W': case 'W':
if (is_next_char('i') || is_next_char('I')) if (is_next_alpha('I'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("with"), TK_WITH); token = expect_token(TBP_EXPECT_TOKEN("WITH"), TK_WITH);
} }
else if (is_next_char('o') || is_next_char('O')) else if (is_next_alpha('O'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("work"), TK_WORK); token = expect_token(TBP_EXPECT_TOKEN("WORK"), TK_WORK);
} }
else if (is_next_char('r') || is_next_char('R')) else if (is_next_alpha('R'))
{ {
token = expect_token(TBP_EXPECT_TOKEN("write"), TK_WRITE); token = expect_token(TBP_EXPECT_TOKEN("WRITE"), TK_WRITE);
} }
break; break;
case '0': case '0':
{ {
char c; char c;
if (!get_next_char(&c) || !isdigit(c)) if (!peek_next_char(&c) || !isdigit(c))
{ {
++m_pI; ++m_pI;
token = TK_ZERO; token = TK_ZERO;