Ejemplo n.º 1
0
        unsafe internal void Sort(Query.DocumentResultForSort[] docResults, int top)
        {
            if (_OrderBys.Count <= 0)
            {
                return;
            }

            QueryResultHeapSort heapSort = new QueryResultHeapSort(_OrderBys, _DBProvider);

            if (heapSort.CanDo)
            {
                heapSort.Prepare(docResults);
                heapSort.TopSort(docResults, top);
                return;
            }

            foreach (SyntaxAnalysis.Select.OrderBy orderBy in _OrderBys)
            {
                Data.Field field = _DBProvider.GetField(orderBy.Name);

                Query.SortType sortType = Hubble.Core.Query.SortType.None;
                bool           isDocId  = false;
                bool           isScore  = false;
                bool           isAsc    = orderBy.Order.Equals("ASC", StringComparison.CurrentCultureIgnoreCase);

                if (field == null)
                {
                    if (orderBy.Name.Equals("DocId", StringComparison.CurrentCultureIgnoreCase))
                    {
                        sortType = Hubble.Core.Query.SortType.Long;
                        isDocId  = true;
                    }
                    else if (orderBy.Name.Equals("Score", StringComparison.CurrentCultureIgnoreCase))
                    {
                        sortType = Hubble.Core.Query.SortType.Long;
                        isScore  = true;
                    }
                    else
                    {
                        throw new ParseException(string.Format("Unknown field name:{0}", orderBy.Name));
                    }
                }
                else
                {
                    if (field.IndexType != Hubble.Core.Data.Field.Index.Untokenized)
                    {
                        throw new ParseException(string.Format("Order by field name:{0} is not Untokenized Index!", orderBy.Name));
                    }
                }

                for (int i = 0; i < docResults.Length; i++)
                {
                    if (docResults[i].SortInfoList == null)
                    {
                        docResults[i].SortInfoList = new List <Hubble.Core.Query.SortInfo>(2);
                    }

                    if (isDocId)
                    {
                        docResults[i].SortInfoList.Add(new Hubble.Core.Query.SortInfo(isAsc, sortType, docResults[i].DocId));
                    }
                    else if (isScore)
                    {
                        docResults[i].SortInfoList.Add(new Hubble.Core.Query.SortInfo(isAsc, sortType, docResults[i].Score));
                    }
                    else
                    {
                        if (docResults[i].PayloadData == null)
                        {
                            int *payloadData = _DBProvider.GetPayloadData(docResults[i].DocId);

                            if (payloadData == null)
                            {
                                throw new ParseException(string.Format("DocId={0} has not payload!", docResults[i].DocId));
                            }

                            docResults[i].PayloadData = payloadData;
                        }

                        docResults[i].SortInfoList.Add(Data.DataTypeConvert.GetSortInfo(isAsc,
                                                                                        field.DataType, docResults[i].PayloadData, field.TabIndex, field.SubTabIndex, field.DataLength));
                    }
                }
            }

            Array.Sort(docResults);

            //Has a bug of partial sort, make comments on following codes until it fixed.
            //if (top <= 0 || top >= docResults.Length/2)
            //{
            //    Array.Sort(docResults);
            //}
            //else
            //{
            //    QuickSort<Query.DocumentResult>.TopSort(docResults, top, new Query.DocumentResultComparer());
            //}
        }