Skip to content

Commit

Permalink
v2.3.1 (#31)
Browse files Browse the repository at this point in the history
* update benchmark results

* refactor field indexing

* fix build warnings (nullable type)

* using lexer instead of regex to parse fieldIndexTokens

* update to v2.3.1
  • Loading branch information
alirezanet authored Oct 19, 2021
1 parent eed8985 commit 3c77265
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 48 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,17 @@ Also, i Should note other features like Pagination and Sorting have almost zero
BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1237 (21H1/May2021Update)
11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK=5.0.301
[Host] : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT
DefaultJob : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT


| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Allocated |
|------------ |-----------:|---------:|---------:|------:|--------:|--------:|--------:|----------:|
| Native LINQ | 724.329 us | 6.4686 us | 6.0507 us | 1.000 | 0.00 | 5.8594 | 2.9297 | 37,392 B |
| Gridify | 736.854 us | 5.7427 us | 5.0907 us | 1.018 | 0.01 | 5.8594 | 2.9297 | 39,924 B |
| DynamicLinq | 886.773 us | 8.4943 us | 7.5299 us | 1.225 | 0.01 | 19.5313 | 9.7656 | 125,122 B |
| Sieve | 961.574 us | 6.6389 us | 5.8852 us | 1.328 | 0.01 | 8.7891 | 3.9063 | 55,186 B |
| Fop | 2,933.332 us | 49.7515 us | 61.0994 us | 4.076 | 0.11 | 46.8750 | 23.4375 | 315,830 B |
| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Allocated |
|------------ |-----------:|---------:|---------:|------:|--------:|--------:|----------:|
| Native LINQ | 740.9 us | 7.80 us | 6.92 us | 1.00 | 5.8594 | 2.9297 | 37 KB |
| Gridify | 762.6 us | 10.06 us | 9.41 us | 1.03 | 5.8594 | 2.9297 | 39 KB |
| DynamicLinq | 902.1 us | 11.56 us | 10.81 us | 1.22 | 19.5313 | 9.7656 | 122 KB |
| Sieve | 977.9 us | 6.80 us | 6.37 us | 1.32 | 7.8125 | 3.9063 | 54 KB |
| Fop | 2,959.8 us | 39.11 us | 36.58 us | 3.99 | 46.8750 | 23.4375 | 306 KB |
---

## Installation
Expand Down
2 changes: 1 addition & 1 deletion benchmark/LibraryComparisionFilteringBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void Gridify()
Ds.ApplyFiltering("Name=Ali", gm).Consume(Consumer);
}

[Benchmark] // compiled query (this is not included in our readme benchmarks)w
// [Benchmark] // compiled query (this is not included in our readme benchmarks)w
public void GridifyCompiled()
{
EnumerableDs.Where(compiled1).Consume(Consumer);
Expand Down
2 changes: 1 addition & 1 deletion src/Gridify.EntityFramework/Gridify.EntityFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Gridify.EntityFramework</PackageId>
<Version>2.3.0</Version>
<Version>2.3.1</Version>
<Authors>Alireza Sabouri</Authors>
<Company>TuxTeam</Company>
<PackageDescription>Gridify (EntityFramework), Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data.</PackageDescription>
Expand Down
2 changes: 1 addition & 1 deletion src/Gridify/Gridify.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Gridify</PackageId>
<Version>2.3.0</Version>
<Version>2.3.1</Version>
<Authors>Alireza Sabouri</Authors>
<Company>TuxTeam</Company>
<PackageDescription>Gridify, Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data.</PackageDescription>
Expand Down
4 changes: 2 additions & 2 deletions src/Gridify/GridifyMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@ public LambdaExpression GetLambdaExpression(string key)
return expression!;
}

public Expression<Func<T,object?>> GetExpression(string key)
public Expression<Func<T,object>> GetExpression(string key)
{
var expression = Configuration.CaseSensitive
? _mappings.FirstOrDefault(q => key.Equals(q.From))?.To
: _mappings.FirstOrDefault(q => key.Equals(q.From, StringComparison.InvariantCultureIgnoreCase))?.To;
if (expression == null)
throw new GridifyMapperException($"Mapping Key `{key}` not found.");
return expression as Expression<Func<T,object?>> ?? throw new GridifyMapperException($"Expression fir the `{key}` not found.");
return expression as Expression<Func<T,object>> ?? throw new GridifyMapperException($"Expression fir the `{key}` not found.");
}

public IEnumerable<IGMap<T>> GetCurrentMaps()
Expand Down
2 changes: 1 addition & 1 deletion src/Gridify/IGridifyMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ IGridifyMapper<T> AddMap(string from, Expression<Func<T, int, object?>> to, Func
IGridifyMapper<T> RemoveMap(string propertyName);
IGridifyMapper<T> RemoveMap(IGMap<T> gMap);
LambdaExpression GetLambdaExpression(string from);
Expression<Func<T, object?>> GetExpression(string key);
Expression<Func<T, object>> GetExpression(string key);
IGMap<T>? GetGMap(string from);
bool HasMap(string key);
public GridifyMapperConfiguration Configuration { get; }
Expand Down
24 changes: 8 additions & 16 deletions src/Gridify/Syntax/FieldExpressionSyntax.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace Gridify.Syntax
{
internal sealed class FieldExpressionSyntax : ExpressionSyntax
{
internal FieldExpressionSyntax(SyntaxToken fieldToken)
{
// for performance reason we simply check the last character first
if (fieldToken.Text.EndsWith("]"))
{
// checking indexes from the field names
var regex = new Regex(@"(\w+)\[(\d+)\]");
var match = regex.Match(fieldToken.Text);
if (!match.Success) throw new ArgumentException($"Invalid filed name '{fieldToken.Text}'");
IsCollection = true;
Index = int.Parse(match.Groups[2].Value);
FieldToken = new SyntaxToken(SyntaxKind.FieldToken, 0, match.Groups[1].Value);
}
else
FieldToken = fieldToken;
FieldToken = fieldToken;
}

public FieldExpressionSyntax(SyntaxToken fieldToken, int index)
{
IsCollection = true;
Index = index;
FieldToken = fieldToken;
}

public override SyntaxKind Kind => SyntaxKind.FieldExpression;

Expand Down
59 changes: 55 additions & 4 deletions src/Gridify/Syntax/Lexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,44 +46,95 @@ public SyntaxToken NextToken()
case '|':
return new SyntaxToken(SyntaxKind.Or, _position++, "|");
case '^':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.StartsWith, _position++, "^");
}
case '$':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.EndsWith, _position++, "$");
}
case '!' when peek == '^':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.NotStartsWith, _position += 2, "!^");
}
case '!' when peek == '$':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.NotEndsWith, _position += 2, "!$");
}
case '=' when peek == '*':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.Like, _position += 2, "=*");
case '=' :
}
case '=':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.Equal, _position ++ , "=");
}
case '!' when peek == '=':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.NotEqual, _position += 2, "!=");
}
case '!' when peek == '*':
{
_waitingForValue = true;
return new SyntaxToken(SyntaxKind.NotLike, _position += 2, "!*");
}
case '/' when peek == 'i':
return new SyntaxToken(SyntaxKind.CaseInsensitive, _position += 2, "/i");
case '<':
{
_waitingForValue = true;
return peek == '=' ? new SyntaxToken(SyntaxKind.LessOrEqualThan, _position += 2, "<=") :
new SyntaxToken(SyntaxKind.LessThan, _position++, "<");
}
case '>':
{
_waitingForValue = true;
return peek == '=' ? new SyntaxToken(SyntaxKind.GreaterOrEqualThan, _position += 2, ">=") :
new SyntaxToken(SyntaxKind.GreaterThan, _position++, ">");
}
}

if (Current == '[')
{
Next();
var start = _position;
while (char.IsDigit(Current))
Next();

var length = _position - start;
var text = _text.Substring(start, length);

if (Current == ']')
{
_position++;
return new SyntaxToken(SyntaxKind.FieldIndexToken, start, text);
}

_diagnostics.Add($"bad character input: '{peek.ToString()}' at {_position++.ToString()}. expected ']' ");
return new SyntaxToken(SyntaxKind.BadToken, _position, Current.ToString());

}

if (char.IsLetter(Current) && !_waitingForValue)
{
var start = _position;

while (char.IsLetterOrDigit(Current) || Current is '_' or '[' or ']')
while (char.IsLetterOrDigit(Current) || Current is '_')
Next();

var length = _position - start;
var text = _text.Substring(start, length);

_waitingForValue = true;

return new SyntaxToken(SyntaxKind.FieldToken, start, text);
}


if (char.IsWhiteSpace(Current))
{
Expand Down
41 changes: 27 additions & 14 deletions src/Gridify/Syntax/Parser.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Gridify.Syntax
{
Expand Down Expand Up @@ -92,10 +94,10 @@ private ExpressionSyntax ParseValueExpression()
// field=
if (Current.Kind != SyntaxKind.ValueToken)
return new ValueExpressionSyntax(new SyntaxToken(), false, true);

var valueToken = Match(SyntaxKind.ValueToken);
var isCaseInsensitive = IsMatch(SyntaxKind.CaseInsensitive);
return new ValueExpressionSyntax(valueToken, isCaseInsensitive,false);
var isCaseInsensitive = IsMatch(SyntaxKind.CaseInsensitive, out _);
return new ValueExpressionSyntax(valueToken, isCaseInsensitive, false);
}

private SyntaxToken NextToken()
Expand All @@ -105,10 +107,15 @@ private SyntaxToken NextToken()
return current;
}

private bool IsMatch(SyntaxKind kind)
private bool IsMatch(SyntaxKind kind, out SyntaxToken token)
{
if (Current.Kind != kind) return false;
NextToken();
if (Current.Kind != kind)
{
token = Current;
return false;
}

token = NextToken();
return true;
}

Expand All @@ -123,15 +130,21 @@ private SyntaxToken Match(SyntaxKind kind)

private ExpressionSyntax ParsePrimaryExpression()
{
if (Current.Kind == SyntaxKind.OpenParenthesisToken)
{
var left = NextToken();
var expression = ParseTerm();
var right = Match(SyntaxKind.CloseParenthesis);
return new ParenthesizedExpressionSyntax(left, expression, right);
}
if (Current.Kind != SyntaxKind.OpenParenthesisToken) return ParseFieldExpression();

var left = NextToken();
var expression = ParseTerm();
var right = Match(SyntaxKind.CloseParenthesis);
return new ParenthesizedExpressionSyntax(left, expression, right);
}

private ExpressionSyntax ParseFieldExpression()
{
var fieldToken = Match(SyntaxKind.FieldToken);

if (IsMatch(SyntaxKind.FieldIndexToken, out SyntaxToken fieldSyntaxToken))
return new FieldExpressionSyntax(fieldToken, int.Parse(fieldSyntaxToken.Text));

return new FieldExpressionSyntax(fieldToken);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Gridify/Syntax/SyntaxKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum SyntaxKind
ParenthesizedExpression,
NotStartsWith,
NotEndsWith,
CaseInsensitive
CaseInsensitive,
FieldIndexToken
}
}

0 comments on commit 3c77265

Please sign in to comment.