public DictionaryFetchAsyncEnumerator(ITransaction tx, IReliableIndexedDictionary <TKey, TValue> dictionary, IEnumerable <TKey> keys, TimeSpan timeout, CancellationToken token) { Tx = tx; Dictionary = dictionary; Keys = keys.GetEnumerator(); Timeout = timeout; Token = token; }
public void TestInitialize() { userDictionaryManager = new MockReliableStateManager(); indexed_users = userDictionaryManager.GetOrAddIndexedAsync <UserName, Basic.Common.UserProfile>("indexed_users", FilterableIndex <UserName, Basic.Common.UserProfile, string> .CreateQueryableInstance("Email"), FilterableIndex <UserName, Basic.Common.UserProfile, int> .CreateQueryableInstance("Age")).Result; for (int i = 0; i < 5; i++) { using (var tx = userDictionaryManager.CreateTransaction()) { var user = new Basic.Common.UserProfile { Name = new UserName { First = $"First{i}", Last = $"Last{i}", }, Email = $"user-{i}@example.com", Age = 20 + i / 3, Address = new Basic.Common.Address { AddressLine1 = $"1{i} Main St.", City = "Seattle", State = "WA", Zipcode = 98117, }, }; indexed_users.SetAsync(tx, user.Name, user, TimeSpan.FromSeconds(4), new CancellationToken()); tx.CommitAsync(); } } Assert.IsTrue(userDictionaryManager.TryGetIndexedAsync <UserName, Basic.Common.UserProfile>("indexed_users", FilterableIndex <UserName, Basic.Common.UserProfile, string> .CreateQueryableInstance("Email"), FilterableIndex <UserName, Basic.Common.UserProfile, int> .CreateQueryableInstance("Age")).Result.HasValue); }
// Executes the expression tree that is passed to it. // Should return internal static async Task <object> Execute <TKey, TValue>(Expression expression, IReliableStateManager stateManager, IReliableIndexedDictionary <TKey, TValue> dictionary, bool IsEnumerable) where TKey : IComparable <TKey>, IEquatable <TKey> { //The expression must represent a query over the data source. if (!IsQueryOverDataSource(expression)) { throw new InvalidProgramException("No query over the data source was specified."); } // Find the call to Where() and get the lambda expression predicate. InnermostWhereFinder whereFinder = new InnermostWhereFinder(); MethodCallExpression whereExpression = whereFinder.GetInnermostWhere(expression); IQueryable <TValue> queryableValues; if (whereExpression != null) { LambdaExpression lambdaExpression = (LambdaExpression)((UnaryExpression)(whereExpression.Arguments[1])).Operand; // Send the lambda expression through the partial evaluator. lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression); // Translate expression to Odata Expression SingleValueNode root = TranslateToOData(lambdaExpression.Body); IEnumerable <TKey> keys = ReliableStateExtensions.TryFilterNode <TKey, TValue>(root, false, stateManager, dictionary.Name.AbsolutePath, new CancellationToken()).Result; IEnumerable <TValue> values; using (var tx = stateManager.CreateTransaction()) { IEnumerable <KeyValuePair <TKey, TValue> > pairs = await dictionary.GetAllAsync(tx, keys, TimeSpan.FromSeconds(4), new CancellationToken()).AsEnumerable(); values = new KeyValueToValueEnumerable <TKey, TValue>(pairs); queryableValues = values.AsQueryable <TValue>(); await tx.CommitAsync(); } } else { IAsyncEnumerable <TValue> values; using (var tx = stateManager.CreateTransaction()) { IAsyncEnumerable <KeyValuePair <TKey, TValue> > pairs = dictionary.CreateEnumerableAsync(tx, EnumerationMode.Ordered).Result; values = new KeyValueToValueAsyncEnumerable <TKey, TValue>(pairs); queryableValues = (values.AsEnumerable().Result).AsQueryable <TValue>(); await tx.CommitAsync(); } } // Copy the expression tree that was passed in, changing only the first // argument of the innermost MethodCallExpression. ExpressionTreeModifier <TKey, TValue> treeCopier = new ExpressionTreeModifier <TKey, TValue>(queryableValues); Expression newExpressionTree = treeCopier.Visit(expression); // This step creates an IQueryable that executes by replacing Queryable methods with Enumerable methods. if (IsEnumerable) { return(queryableValues.Provider.CreateQuery(newExpressionTree)); } else { return(queryableValues.Provider.Execute(newExpressionTree)); } // This step creates an IQueryable that executes by replacing Queryable methods with Enumerable methods. }
// This is a seperate method because we now know PropertyType, so want to not use reflection in above method public static async Task <IEnumerable <TKey> > FilterHelper <TKey, TValue, TFilter>(IReliableIndexedDictionary <TKey, TValue> dictionary, TFilter constant, BinaryOperatorKind strategy, bool notIsApplied, CancellationToken cancellationToken, IReliableStateManager stateManager, string propertyName) where TFilter : IComparable <TFilter>, IEquatable <TFilter> where TKey : IComparable <TKey>, IEquatable <TKey> { using (var tx = stateManager.CreateTransaction()) { IEnumerable <TKey> result; // Equals if ((strategy == BinaryOperatorKind.Equal && !notIsApplied) || (strategy == BinaryOperatorKind.NotEqual && notIsApplied)) { result = await dictionary.FilterKeysOnlyAsync(tx, propertyName, constant, TimeSpan.FromSeconds(4), cancellationToken); } else if ((strategy == BinaryOperatorKind.GreaterThan && !notIsApplied) || (strategy == BinaryOperatorKind.LessThan && notIsApplied)) { result = await dictionary.RangeFromFilterKeysOnlyAsync(tx, propertyName, constant, RangeFilterType.Exclusive, TimeSpan.FromSeconds(4), cancellationToken); } else if ((strategy == BinaryOperatorKind.GreaterThanOrEqual && !notIsApplied) || (strategy == BinaryOperatorKind.LessThanOrEqual && notIsApplied)) { result = await dictionary.RangeFromFilterKeysOnlyAsync(tx, propertyName, constant, RangeFilterType.Inclusive, TimeSpan.FromSeconds(4), cancellationToken); } else if ((strategy == BinaryOperatorKind.LessThan && !notIsApplied) || (strategy == BinaryOperatorKind.GreaterThan && notIsApplied)) { result = await dictionary.RangeToFilterKeysOnlyAsync(tx, propertyName, constant, RangeFilterType.Exclusive, TimeSpan.FromSeconds(4), cancellationToken); } else if ((strategy == BinaryOperatorKind.LessThanOrEqual && !notIsApplied) || (strategy == BinaryOperatorKind.GreaterThanOrEqual && notIsApplied)) { result = await dictionary.RangeToFilterKeysOnlyAsync(tx, propertyName, constant, RangeFilterType.Inclusive, TimeSpan.FromSeconds(4), cancellationToken); } else { // Bad State, should never hit throw new NotSupportedException("Does not support Add, Subtract, Modulo, Multiply, Divide operations."); } await tx.CommitAsync(); return(result); } }
public ReliableIndexedDictionaryProvider(IReliableIndexedDictionary <TKey, TValue> indexedDictionary, IReliableStateManager stateManager) { Dictionary = indexedDictionary ?? throw new ArgumentNullException("Dictionary can not be null"); StateManager = stateManager ?? throw new ArgumentNullException("StateManager can not be null"); }
public QueryableReliableIndexedDictionary(IReliableIndexedDictionary <TKey, TValue> dictionary, IReliableStateManager stateManager) { Provider = new ReliableIndexedDictionaryProvider <TKey, TValue>(dictionary, stateManager); Expression = Expression.Constant(this); }