private long HighestSearch(IndexKey ob, BigList <long> list, long lower, long higher)
        {
            if ((higher - lower) <= 5)
            {
                // Start from the bottom up until we find the highest val
                for (var i = higher; i >= lower; --i)
                {
                    int res = ob.CompareTo(GetKey(list[i]));
                    if (res >= 0)
                    {
                        return(i + 1);
                    }
                }
                // Didn't find return lowest
                return(lower);
            }

            var mid        = (lower + higher) / 2;
            int compResult = ob.CompareTo(GetKey(list[mid]));

            if (compResult == 0)
            {
                // We know the bottom is between 'mid' and 'higher'
                return(HighestSearch(ob, list, mid, higher));
            }

            if (compResult < 0)
            {
                return(HighestSearch(ob, list, lower, mid - 1));
            }

            return(HighestSearch(ob, list, mid + 1, higher));
        }
        public static void CompareSingleValue(object value1, object value2, int expetced)
        {
            var key1 = new IndexKey(SqlObject.New(SqlValueUtil.FromObject(value1)));
            var key2 = new IndexKey(SqlObject.New(SqlValueUtil.FromObject(value2)));

            Assert.Equal(expetced, key1.CompareTo(key2));
        }
        public static void CompareMultipleValue(object value1a, object value1b, object value2a, object value2b, int expetced)
        {
            var key1 = new IndexKey(new[] {
                SqlObject.New(SqlValueUtil.FromObject(value1a)),
                SqlObject.New(SqlValueUtil.FromObject(value1b))
            });
            var key2 = new IndexKey(new[] {
                SqlObject.New(SqlValueUtil.FromObject(value2a)),
                SqlObject.New(SqlValueUtil.FromObject(value2b))
            });

            Assert.Equal(expetced, key1.CompareTo(key2));
        }
        private static IndexRange IntersectOn(IndexRange range, SqlExpressionType op, IndexKey value, bool nullCheck)
        {
            var start         = range.StartValue;
            var startPosition = range.StartOffset;
            var end           = range.EndValue;
            var endPosition   = range.EndOffset;

            bool inclusive = op == SqlExpressionType.Is ||
                             op == SqlExpressionType.Equal ||
                             op == SqlExpressionType.GreaterThanOrEqual ||
                             op == SqlExpressionType.LessThanOrEqual;

            if (op == SqlExpressionType.Is ||
                op == SqlExpressionType.Equal ||
                op == SqlExpressionType.GreaterThan ||
                op == SqlExpressionType.GreaterThanOrEqual)
            {
                // With this operator, NULL values must return null.
                if (nullCheck && value.IsNull)
                {
                    return(IndexRange.Null);
                }

                if (start.Equals(IndexRange.FirstInSet))
                {
                    start         = value;
                    startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue;
                }
                else
                {
                    int c = value.CompareTo(start);
                    if ((c == 0 && startPosition == RangeFieldOffset.FirstValue) || c > 0)
                    {
                        start         = value;
                        startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue;
                    }
                }
            }

            if (op == SqlExpressionType.Is ||
                op == SqlExpressionType.Equal ||
                op == SqlExpressionType.LessThan ||
                op == SqlExpressionType.LessThanOrEqual)
            {
                // With this operator, NULL values must return null.
                if (nullCheck && value.IsNull)
                {
                    return(IndexRange.Null);
                }

                // If start is first in set, then we have to change it to after NULL
                if (nullCheck && start.Equals(IndexRange.FirstInSet))
                {
                    start         = value.NullKey;
                    startPosition = RangeFieldOffset.AfterLastValue;
                }

                if (end.Equals(IndexRange.LastInSet))
                {
                    end         = value;
                    endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue;
                }
                else
                {
                    int c = value.CompareTo(end);
                    if ((c == 0 && endPosition == RangeFieldOffset.LastValue) || c < 0)
                    {
                        end         = value;
                        endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue;
                    }
                }
            }

            // If start and end are not null types (if either are, then it means it
            // is a placeholder value meaning start or end of set).
            if (!start.Equals(IndexRange.FirstInSet) &&
                !end.Equals(IndexRange.LastInSet))
            {
                // If start is higher than end, return null
                int c = start.CompareTo(end);
                if ((c == 0 && (startPosition == RangeFieldOffset.AfterLastValue ||
                                endPosition == RangeFieldOffset.BeforeFirstValue)) ||
                    c > 0)
                {
                    return(IndexRange.Null);
                }
            }

            // The new intersected range
            return(new IndexRange(startPosition, start, endPosition, end));
        }