Skip to content

Commit

Permalink
Optimize lexem state lookups.
Browse files Browse the repository at this point in the history
  • Loading branch information
Remi Caput committed Jan 29, 2017
1 parent 8ac1ddb commit e8fb776
Showing 1 changed file with 46 additions and 17 deletions.
63 changes: 46 additions & 17 deletions Cottle/src/Parsers/Default/LexemState.cs
Expand Up @@ -4,6 +4,12 @@ namespace Cottle.Parsers.Default
{
class LexemState
{
#region Constants

private const int BRANCH_LIMIT = 256;

#endregion

#region Properties

public LexemType Type
Expand All @@ -18,9 +24,11 @@ public LexemType Type

#region Attributes

private readonly Dictionary<char, LexemState> branches = new Dictionary<char, LexemState> ();
private Dictionary<char, LexemState> branchesHigh = null;

private LexemType type = LexemType.None;
private LexemState[] branchesLow = null;

private LexemType type = LexemType.None;

#endregion

Expand All @@ -30,38 +38,59 @@ public LexemState Follow (char character)
{
LexemState state;

if (this.branches.TryGetValue (character, out state))
if (this.branchesLow != null && character < LexemState.BRANCH_LIMIT)
return this.branchesLow[character];
else if (this.branchesHigh != null && this.branchesHigh.TryGetValue (character, out state))
return state;

return null;
}

public bool Store (LexemType type, string content)
{
char character;
LexemState state;
LexemState current;
LexemState next;

if (content.Length > 0)
current = this;

foreach (char character in content)
{
character = content[0];
if (character < LexemState.BRANCH_LIMIT)
{
if (current.branchesLow == null)
current.branchesLow = new LexemState[LexemState.BRANCH_LIMIT];

if (!this.branches.TryGetValue (character, out state))
next = current.branchesLow[character];

if (next == null)
{
next = new LexemState ();

current.branchesLow[character] = next;
}
}
else
{
state = new LexemState ();
if (current.branchesHigh == null)
current.branchesHigh = new Dictionary<char, LexemState> ();

if (!current.branchesHigh.TryGetValue (character, out next))
{
next = new LexemState ();

this.branches[character] = state;
current.branchesHigh[character] = next;
}
}

return state.Store (type, content.Substring (1));
current = next;
}
else if (this.type == LexemType.None)
{
this.type = type;

return true;
}
if (current.type != LexemType.None)
return false;

current.type = type;

return false;
return true;
}

#endregion
Expand Down

0 comments on commit e8fb776

Please sign in to comment.