Ejemplo n.º 1
0
        /// <summary>
        /// Checks whether the tree has B-Tree properties.
        /// </summary>
        /// <typeparam name="TNode">Type of the tree nodes stored in the tree. </typeparam>
        /// <typeparam name="TKey">Type of the keys stored in the tree. </typeparam>
        /// <typeparam name="TValue">Type of the values stored in the tree. </typeparam>
        /// <param name="tree">A B-Tree</param>
        /// <param name="expectedTotalKeyCount">The expected number of keys (duplicate and distinct) in the tree. </param>
        /// <param name="expectedDistinctKeyCount">The expected number of distinct keys in the tree. </param>
        /// <param name="expectedNodeCount">The expected number of tree nodes. </param>
        /// <param name="HasNodeProperties">The method used for checking properties. </param>
        /// <returns>True if the tree has the expected properties. </returns>
        public static bool HasBTreeProperties <TNode, TKey, TValue>(BTreeBase <TNode, TKey, TValue> tree, int expectedTotalKeyCount, int expectedDistinctKeyCount, int expectedNodeCount, Func <TNode, bool> HasNodeProperties) where TNode : IBTreeNode <TNode, TKey, TValue>, IComparable <TNode> where TKey : IComparable <TKey>
        {
            var nodes = new List <TNode>();

            DFS <TNode, TKey, TValue>(tree.Root, nodes);
            Assert.AreEqual(expectedNodeCount, nodes.Count);

            int keyCount = 0;

            /* Checking whether all the nodes are proper BTree nodes. */
            foreach (TNode node in nodes)
            {
                Assert.IsTrue(HasNodeProperties(node));
                keyCount += node.KeyCount;
            }

            /* Check that key count matches the expected key count. */
            Assert.AreEqual(expectedTotalKeyCount, keyCount);

            /* Get the sorted key list and make sure it is sorted. */

            if (tree.Root != null)
            {
                List <KeyValuePair <TKey, TValue> > sortedKeys = tree.GetSortedKeyValues(tree.Root);

                Assert.AreEqual(expectedDistinctKeyCount, sortedKeys.Count);
                for (int i = 0; i < sortedKeys.Count - 1; i++)
                {
                    Assert.IsTrue(sortedKeys[i].Key.CompareTo(sortedKeys[i + 1].Key) < 0);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        static IEnumerable <Key> Equal <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp)
#if WINDOWS_PHONE
            where Key : new()
#endif
        {
            SessionBase          session   = sourceCollection.Session;
            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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        static bool GreaterThanOrEqualUseIndex <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp)
#if WINDOWS_PHONE
            where Key : new()
#endif
        {
            SessionBase          session  = sourceCollection.Session;
            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);
        }
Ejemplo n.º 4
0
        static bool GreaterThanUseIndex <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);
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 5
0
        private static bool HasIndexablePropertyOnLeft <Key>(Expression leftSide, BTreeBase <Key, Key> sourceCollection, DataMember dataMember, out MemberExpression theMember)
#if WINDOWS_PHONE
            where Key : new()
#endif
        {
            theMember = null;
            MemberExpression mex = leftSide as MemberExpression;

            if (leftSide.NodeType == ExpressionType.Convert)
            {
                UnaryExpression convert = leftSide as UnaryExpression;
                mex = convert.Operand as MemberExpression;
            }
            if (leftSide.NodeType == ExpressionType.Call)
            {
                MethodCallExpression call = leftSide as MethodCallExpression;
                if (call.Method.Name == "CompareString")
                {
                    mex = call.Arguments[0] as MemberExpression;
                }
            }
            else if (mex == null)
            {
                return(false);
            }
            else
            {
                theMember = mex;
                if (dataMember.Field.Name == mex.Member.Name)
                {
                    return(true);
                }
                FieldAccessor accessor = CustomAttributeExtensions.GetCustomAttribute <FieldAccessor>(theMember.Member, true);
                if (accessor != null)
                {
                    return(dataMember.Field.Name == accessor.FieldName);
                }
            }
            return(false);
        }
Ejemplo n.º 6
0
        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.Session;

            if (session.TraceIndexUsage)
            {
                Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString());
            }
            return(true);
        }
Ejemplo n.º 7
0
        static IEnumerable <Key> And <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp)
#if WINDOWS_PHONE
            where Key : new()
#endif
        {
            CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>;
            int indexNumberOfFields       = comparer.FieldsToCompare.Length;

#if WINDOWS_PHONE || WINDOWS_UWP
            Key key = (Key)Activator.CreateInstance(typeof(Key));
#else
            Key key = (Key)FormatterServices.GetUninitializedObject(typeof(Key));
#endif
            while (binExp.NodeType == ExpressionType.AndAlso)
            {
                BinaryExpression leftExpr   = (BinaryExpression)binExp.Left;
                BinaryExpression rightExpr  = (BinaryExpression)binExp.Right;
                DataMember       dataMember = comparer.FieldsToCompare[--indexNumberOfFields];
                object           rightValue = GetRightValue(rightExpr.Left, rightExpr.Right);
                dataMember.SetMemberValueWithPossibleConvert(key, rightValue);
                binExp = leftExpr;
                if (binExp.NodeType == ExpressionType.Equal)
                {
                    dataMember = comparer.FieldsToCompare[--indexNumberOfFields];
                    rightValue = GetRightValue(binExp.Left, binExp.Right);
                    dataMember.SetMemberValueWithPossibleConvert(key, rightValue);
                }
            }
            BTreeSetIterator <Key> itr = sourceCollection.Iterator();
            itr.GoTo(key);
            Key current = itr.Current();
            while (current != null && comparer.Compare(key, current) == 0)
            {
                yield return(current);

                current = itr.Next();
            }
        }
Ejemplo n.º 8
0
        static bool canUseIndex <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp, CompareByField <Key> comparer)
#if WINDOWS_PHONE
            where Key : new()
#endif
        {
            if (comparer.FieldsToCompare == null)
            {
                comparer.SetupFieldsToCompare();
            }
            int indexNumberOfFields = comparer.FieldsToCompare.Length;

            while (binExp.NodeType == ExpressionType.AndAlso)
            {
                BinaryExpression leftExpr   = (BinaryExpression)binExp.Left;
                BinaryExpression rightExpr  = (BinaryExpression)binExp.Right;
                MemberExpression returnedEx = null;
                if (indexNumberOfFields == 0 || !HasIndexablePropertyOnLeft(rightExpr.Left, sourceCollection, comparer.FieldsToCompare[--indexNumberOfFields], out returnedEx))
                {
                    return(false);
                }
                binExp = leftExpr;
            }
            return(true);
        }
Ejemplo n.º 9
0
        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.Session;
                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);
                    }
                }
            }
        }
Ejemplo n.º 10
0
        static IEnumerable <Key> LessThan <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp)
#if WINDOWS_PHONE
            where Key : new()
#endif
        {
            SessionBase          session    = sourceCollection.Session;
            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 */
                    }
                }
            }
        }
Ejemplo n.º 11
0
 static public int Count <Key>(this BTreeBase <Key, Key> sourceCollection)
 {
     return(sourceCollection.Count);
 }
Ejemplo n.º 12
0
        string DisplayData(bool useServerSession)
        {
            using (SessionBase session = useServerSession ? (SessionBase) new ServerClientSession(systemDir) : (SessionBase) new SessionNoServer(systemDir))
            {
                StringBuilder sb = new StringBuilder();
                session.BeginRead();
                try
                {
                    BTreeBase <RDerby1, RDerby1> index = null;
                    try
                    {
                        session.Index <RDerby1>();
                    }
                    catch (IndexDatabaseNotSpecifiedException)
                    {
                        UInt32   dbId = session.DatabaseNumberOf(typeof(RDerby1));
                        Database db   = session.OpenDatabase(dbId);
                        index = session.Index <RDerby1>(db);
                    }

                    // for testing
                    //var index = session.Index<Test1_0_0Class>("name2");


                    // create variable so that can examine in Locals

                    if (index != null) // should not be null?
                    {
                        // get all
                        var testEntries = from t in index
                                          select t;

                        int count = testEntries.ToList <RDerby1>().Count;
                        int i     = 0;

                        sb.AppendLine("Session Details:");
                        sb.AppendLine(index.ToStringDetails(session));
                        sb.AppendLine("Results:");
                        foreach (RDerby1 test in testEntries)
                        {
                            try
                            {
                                string values = test.Name + ", " + test.Name2 + ", " + test.Added;

                                sb.AppendLine(string.Format("{0, -5:00000}: {1}", i++, values));
                            }
                            catch (Exception ex)
                            {
                                return("Exception thrown in for each loop: " + ex.Message);
                            }
                        }
                    }
                    else
                    {
                        return("Index was null");
                        // why is the index null?
                    }
                }
                catch (Exception ex)
                {
                    return("Exception occured prior to loop: " + ex.Message);
                    // examine problem using breakpoint.
                }
                finally
                {
                    session.Commit();
                }
                return(sb.ToString());
            }
        }