static IEnumerable <Key> Equal <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { SessionBase session = sourceCollection.GetSession(); CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; Expression leftSide = binExp.Left; Expression rightSide = binExp.Right; object rightValue = GetRightValue(leftSide, rightSide); if (leftSide.NodeType == ExpressionType.Parameter) { Key key = (Key)rightValue; if (key != null) { BTreeSetIterator <Key> itr = sourceCollection.Iterator(); itr.GoTo(key); while (sourceCollection.Comparer.Compare(itr.Current(), key) == 0) { yield return(itr.Next()); } } } else { if (comparer != null) { MemberExpression returnedEx = null; #if WINDOWS_PHONE || WINDOWS_UWP Key key = (Key)Activator.CreateInstance(typeof(Key)); #else Key key = (Key)FormatterServices.GetUninitializedObject(typeof(Key)); #endif if (comparer.FieldsToCompare == null) { comparer.SetupFieldsToCompare(); } DataMember dataMember = comparer.FieldsToCompare[0]; if (rightValue != null && HasIndexablePropertyOnLeft <Key>(leftSide, sourceCollection, dataMember, out returnedEx)) { MemberExpression propExp = (MemberExpression)returnedEx; MemberInfo property = propExp.Member; dataMember.SetMemberValueWithPossibleConvert(key, rightValue); BTreeSetIterator <Key> itr = sourceCollection.Iterator(); itr.GoTo(key); Key current = itr.Current(); while (current != null && comparer.CompareField(dataMember, key, current, 0) == 0) { yield return(current); current = itr.Next(); } } } } }
static bool GreaterThanOrEqualUseIndex <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { SessionBase session = sourceCollection.GetSession(); CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; Expression leftSide = binExp.Left; Expression rightSide = binExp.Right; object rightValue = GetRightValue(leftSide, rightSide); if (leftSide.NodeType == ExpressionType.Parameter) { Key key = (Key)rightValue; if (key != null) { if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); } } else { if (comparer != null) { //if we were able to create a hash from the right side (likely) MemberExpression returnedEx = null; if (comparer.FieldsToCompare == null) { comparer.SetupFieldsToCompare(); } DataMember dataMember = comparer.FieldsToCompare[0]; if (rightValue != null && HasIndexablePropertyOnLeft <Key>(leftSide, sourceCollection, dataMember, out returnedEx)) { if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); } else if (leftSide.NodeType == ExpressionType.Call) { // don't know yet how to handle TODO /*MethodCallExpression expression = leftSide as MethodCallExpression; * Trace.Out.WriteLine("Method: " + expression.Method.Name); * Trace.Out.WriteLine("Args: "); * foreach (var exp in expression.Arguments) * sourceCollection where */ } } } return(false); }
static bool EqualUseIndex <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { SessionBase session = sourceCollection.GetSession(); CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; Expression leftSide = binExp.Left; Expression rightSide = binExp.Right; object rightValue = GetRightValue(leftSide, rightSide); if (leftSide.NodeType == ExpressionType.Parameter) { Key key = (Key)rightValue; if (key != null) { if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); } } else { if (comparer != null) { MemberExpression returnedEx = null; if (comparer.FieldsToCompare == null) { comparer.SetupFieldsToCompare(); } DataMember dataMember = comparer.FieldsToCompare[0]; if (rightValue != null && HasIndexablePropertyOnLeft <Key>(leftSide, sourceCollection, dataMember, out returnedEx)) { if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); } } } return(false); }
static bool AndUseIndex <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { while (binExp.NodeType == ExpressionType.AndAlso) { BinaryExpression leftExpr = (BinaryExpression)binExp.Left; binExp = leftExpr; if (binExp.NodeType != ExpressionType.Equal && binExp.NodeType != ExpressionType.AndAlso) { return(false); } } SessionBase session = sourceCollection.GetSession(); if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); }
static public IEnumerable <Key> Where <Key>(this BTreeBase <Key, Key> sourceCollection, Expression <Func <Key, bool> > expr) #if WINDOWS_PHONE where Key : new() #endif { if (sourceCollection != null) { bool noIndex = true; SessionBase session = sourceCollection.GetSession(); CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; BinaryExpression binExp = expr.Body as BinaryExpression; if (binExp != null && canUseIndex <Key>(sourceCollection, binExp, comparer)) { session.WaitForIndexUpdates(); switch (expr.Body.NodeType) { case ExpressionType.AndAlso: { noIndex = AndUseIndex(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in And <Key>(sourceCollection, binExp)) { yield return(x); } } else { BinaryExpression leftExpr = (BinaryExpression)binExp.Left; binExp = leftExpr; switch (binExp.NodeType) { case ExpressionType.Equal: { noIndex = EqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> equal = Equal <Key>(sourceCollection, binExp); IEnumerable <Key> result = equal.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.LessThan: { noIndex = LessThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> lessThan = LessThan <Key>(sourceCollection, binExp); IEnumerable <Key> result = lessThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.LessThanOrEqual: { noIndex = LessThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> lessThan = LessThanOrEqual <Key>(sourceCollection, binExp); IEnumerable <Key> result = lessThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.GreaterThan: { noIndex = GreaterThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> greaterThan = GreaterThan <Key>(sourceCollection, binExp); IEnumerable <Key> result = greaterThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.GreaterThanOrEqual: { noIndex = GreaterThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> greaterThan = GreaterThanOrEqual <Key>(sourceCollection, binExp); IEnumerable <Key> result = greaterThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } } ; } } break; case ExpressionType.Equal: { noIndex = EqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in Equal <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.GreaterThan: { noIndex = GreaterThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in GreaterThan <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.GreaterThanOrEqual: { noIndex = GreaterThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in GreaterThanOrEqual <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.LessThan: { noIndex = LessThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in LessThan <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.LessThanOrEqual: { noIndex = LessThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in LessThanOrEqual <Key>(sourceCollection, binExp)) { yield return(x); } } } break; } } if (noIndex) //no index? just do it the normal slow way then... { IEnumerable <Key> sourceEnum; if (sourceCollection.UsesOidShort) { BTreeSetOidShort <Key> c = (BTreeSetOidShort <Key>)sourceCollection; sourceEnum = c.AsEnumerable <Key>(); } else { BTreeSet <Key> c = (BTreeSet <Key>)sourceCollection; sourceEnum = c.AsEnumerable <Key>(); } IEnumerable <Key> result = sourceEnum.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } } }
static IEnumerable <Key> LessThan <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { SessionBase session = sourceCollection.GetSession(); Expression leftSide = binExp.Left; Expression rightSide = binExp.Right; object rightValue = GetRightValue(leftSide, rightSide); CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; if (leftSide.NodeType == ExpressionType.Parameter) { Key key = (Key)rightValue; if (key != null) { BTreeSetIterator <Key> itr = sourceCollection.Iterator(); if (itr.GoTo(key)) { while (itr.Previous() != null) { yield return(itr.Current()); } } } } else { if (comparer != null) { //if we were able to create a hash from the right side (likely) MemberExpression returnedEx = null; #if WINDOWS_PHONE || WINDOWS_UWP Key key = (Key)Activator.CreateInstance(typeof(Key)); #else Key key = (Key)FormatterServices.GetUninitializedObject(typeof(Key)); #endif if (comparer.FieldsToCompare == null) { comparer.SetupFieldsToCompare(); } DataMember dataMember = comparer.FieldsToCompare[0]; if (rightValue != null && HasIndexablePropertyOnLeft <Key>(leftSide, sourceCollection, dataMember, out returnedEx)) { //cast to MemberExpression - it allows us to get the property MemberExpression propExp = (MemberExpression)returnedEx; MemberInfo property = propExp.Member; foreach (DataMember member in comparer.FieldsToCompare.Skip(1)) { if (member.GetTypeCode == TypeCode.String) { member.SetMemberValue(key, ""); } } dataMember.SetMemberValueWithPossibleConvert(key, rightValue); BTreeSetIterator <Key> itr = sourceCollection.Iterator(); itr.GoTo(key); var v = itr.Current(); if (v == null) { v = itr.Previous(); } while (v != null && comparer.CompareField(dataMember, key, v, 0) == 0) { v = itr.Previous(); } while (v != null) { yield return(v); v = itr.Previous(); } } else if (leftSide.NodeType == ExpressionType.Call) { // don't know yet how to handle TODO /*MethodCallExpression expression = leftSide as MethodCallExpression; * Trace.Out.WriteLine("Method: " + expression.Method.Name); * Trace.Out.WriteLine("Args: "); * foreach (var exp in expression.Arguments) * sourceCollection where */ } } } }