Beispiel #1
0
        public int Count()
        {
            lock (this.store._Locker)
            {
                int skipped = 0;
                int taken   = 0;

                ExecutionPlan executionplan = FilterParser <TKey, TValue> .GetExecutionPlan(this);

                List <List <long> > rangelist  = new List <List <long> >();
                List <TValue>       returnlist = new List <TValue>();

                foreach (var item in executionplan.indexRanges)
                {
                    /// check if the primary key is included.

                    List <long> blockpositionList = new List <long>();

                    ItemCollection collection = this.store.Indexes.getIndex(item.Key).GetCollection(item.Value.lower, item.Value.upper, item.Value.lowerOpen, item.Value.upperOpen, this.Ascending);

                    foreach (Int64 position in collection)
                    {
                        blockpositionList.Add(position);
                    }

                    rangelist.Add(blockpositionList);
                }

                bool itemMatch = true;

                foreach (Int64 item in executionplan.startCollection)
                {
                    /// check matches.
                    itemMatch = true;
                    foreach (List <long> rangeitem in rangelist)
                    {
                        if (!rangeitem.Contains(item))
                        {
                            itemMatch = false;
                            break;
                        }
                    }

                    if (!itemMatch)
                    {
                        continue;
                    }


                    /// check column matchs.
                    foreach (ColumnScan plan in executionplan.scanColumns)
                    {
                        byte[] columnbytes = this.store.getColumnsBytes(item, plan.relativeStartPosition, plan.length);

                        if (!plan.Evaluator.isMatch(columnbytes))
                        {
                            itemMatch = false;
                            break;
                        }
                    }

                    if (!itemMatch)
                    {
                        continue;
                    }

                    /// pass all tests.

                    if (skipped < this.SkipCount)
                    {
                        skipped += 1;
                        continue;
                    }


                    taken += 1;
                }

                executionplan = null;

                return(taken);
            }
        }
Beispiel #2
0
        /// <summary>
        /// prase the filter collection and get an execution plan.
        /// </summary>
        /// <returns></returns>
        public static ExecutionPlan GetExecutionPlan(Filter <TKey, TValue> filter)
        {
            ExecutionPlan executionplan = new ExecutionPlan();

            //first check order by field.
            if (filter.OrderByPrimaryKey)
            {
                // does not support range with primary key yet, will be supported later.
                Range <byte[]> primaryrange = getRange(filter.store.StoreSetting.PrimaryKey, filter.items);

                if (primaryrange != null)
                {
                    executionplan.startCollection = filter.store.primaryIndex.getCollection(primaryrange.lower, primaryrange.upper, primaryrange.lowerOpen, primaryrange.upperOpen, filter.Ascending);
                }
                else
                {
                    executionplan.startCollection = filter.store.primaryIndex.allItemCollection(filter.Ascending);
                }

                // executionplan.OrderBySettled = true;
                executionplan.hasStartCollection = true;
            }
            else
            {
                if (!string.IsNullOrEmpty(filter.OrderByFieldName))
                {
                    if (filter.store.Indexes.HasIndex(filter.OrderByFieldName))
                    {
                        Range <byte[]> range = getRange(filter.OrderByFieldName, filter.items);

                        if (range != null)
                        {
                            executionplan.startCollection = filter.store.Indexes.getIndex(filter.OrderByFieldName).GetCollection(range.lower, range.upper, range.lowerOpen, range.upperOpen, filter.Ascending);
                        }
                        else
                        {
                            executionplan.startCollection = filter.store.Indexes.getIndex(filter.OrderByFieldName).AllItems(filter.Ascending);
                        }

                        // executionplan.OrderBySettled = true;
                        executionplan.hasStartCollection = true;
                    }
                }
            }

            // check the primary key index.
            Range <byte[]> primarykeyrange = getRange(filter.store.StoreSetting.PrimaryKey, filter.items);

            if (primarykeyrange != null)
            {
                executionplan.startCollection    = filter.store.primaryIndex.getCollection(primarykeyrange.lower, primarykeyrange.upper, primarykeyrange.lowerOpen, primarykeyrange.upperOpen, filter.Ascending);
                executionplan.hasStartCollection = true;
            }

            // check all index fields that has been used in the filter.
            foreach (var item in filter.store.Indexes.items)
            {
                Range <byte[]> indexrange = getRange(item.FieldName, filter.items);
                if (indexrange != null)
                {
                    executionplan.indexRanges.Add(item.FieldName, indexrange);
                }
            }

            // now parse columns. All query where condition item must be in columns, otherwise this will be a problem.
            foreach (var item in filter.items)
            {
                Columns.IColumn <TValue> column;
                column = filter.store.GetColumn(item.FieldOrProperty);
                if (column != null)
                {
                    ColumnScan colplan = new ColumnScan();

                    colplan.ColumnName            = column.FieldName;
                    colplan.relativeStartPosition = column.relativePosition;
                    colplan.length    = column.Length;
                    colplan.Evaluator = ColumnEvaluator.GetEvaluator(column.DataType, item.Compare, item.Value, column.Length);

                    executionplan.scanColumns.Add(colplan);
                }
                else
                {
                    throw new Exception("filter field must be index or column, add them to colomn or index when creating the store, otherwise use the fullscan option");
                }
            }

            foreach (var item in filter.InItems)
            {
                Columns.IColumn <TValue> column;
                column = filter.store.GetColumn(item.Key);
                if (column != null)
                {
                    ColumnScan colplan = new ColumnScan();

                    colplan.ColumnName            = column.FieldName;
                    colplan.relativeStartPosition = column.relativePosition;
                    colplan.length    = column.Length;
                    colplan.Evaluator = ColumnInEvaluator.GetInEvaluator(column.DataType, item.Value, column.Length);

                    executionplan.scanColumns.Add(colplan);
                }
                else
                {
                    throw new Exception("filter field must be index or column, add them to colomn or index when creating the store, otherwise use the fullscan option");
                }
            }

            /// for the methods calls.
            foreach (var item in filter.calls)
            {
                MemberExpression memberaccess = null;
                foreach (var xitem in item.Arguments)
                {
                    if (xitem.NodeType == ExpressionType.MemberAccess)
                    {
                        memberaccess = xitem as MemberExpression;
                    }
                }
                if (memberaccess == null)
                {
                    throw new Exception("Method call require use one of the Fields or Property as parameters");
                }

                string fieldname = memberaccess.Member.Name;

                Columns.IColumn <TValue> column;
                column = filter.store.GetColumn(fieldname);
                if (column != null)
                {
                    ColumnScan colplan = new ColumnScan();

                    colplan.ColumnName            = column.FieldName;
                    colplan.relativeStartPosition = column.relativePosition;
                    colplan.length = column.Length;

                    colplan.Evaluator = ColumnMethodCallEvaluator.GetMethodEvaluator(column.DataType, column.Length, item);

                    executionplan.scanColumns.Add(colplan);
                }
                else
                {
                    throw new Exception("methed call parameter must be a column, add the field to colomn creating creating the store, otherwise use the fullscan option");
                }
            }
            /// verify the plan. or optimize it.
            if (!executionplan.hasStartCollection)
            {
                //make one of the range. pick any one now. should be pick by the optimizer.
                foreach (var item in executionplan.indexRanges)
                {
                    IIndex <TValue> index = filter.store.Indexes.getIndex(item.Key);
                    if (index != null)
                    {
                        executionplan.startCollection    = index.GetCollection(item.Value.lower, item.Value.upper, item.Value.lowerOpen, item.Value.upperOpen, filter.Ascending);
                        executionplan.hasStartCollection = true;
                        executionplan.indexRanges.Remove(item.Key);
                        break;
                    }
                }
                if (!executionplan.hasStartCollection)
                {
                    executionplan.startCollection    = filter.store.primaryIndex.allItemCollection(filter.Ascending);
                    executionplan.hasStartCollection = true;
                }
            }

            return(executionplan);
        }