Пример #1
0
        /// <summary>
        /// Searches an index for the specified string.
        /// </summary>
        /// <param name="indexId">The index id.</param>
        /// <param name="wsId">The ws id.</param>
        /// <param name="text">The text.</param>
        /// <returns>The search results.</returns>
        public IEnumerable <T> Search(int indexId, int wsId, string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(Enumerable.Empty <T>());
            }

            SortKeyIndex index = GetIndex(indexId, wsId);

            switch (m_type)
            {
            case SearchType.Exact:
            case SearchType.Prefix:
            {
                byte[] sortKey = m_sortKeySelector(wsId, text);
                var    lower   = new byte[text.Length * SortKeyFactor];
                Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower);
                var upper = new byte[text.Length * SortKeyFactor];
                Icu.GetSortKeyBound(sortKey,
                                    m_type == SearchType.Exact
                                                                                                ? Icu.UColBoundMode.UCOL_BOUND_UPPER
                                                                                                : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper);

                return(index.GetItems(lower, upper));
            }

            case SearchType.FullText:
                IEnumerable <T> results = null;
                string[]        tokens  = RemoveWhitespaceAndPunctTokens(m_tokenizer(wsId, text)).ToArray();
                for (int i = 0; i < tokens.Length; i++)
                {
                    byte[] sortKey = m_sortKeySelector(wsId, tokens[i]);
                    var    lower   = new byte[tokens[i].Length * SortKeyFactor];
                    Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower);
                    var upper = new byte[tokens[i].Length * SortKeyFactor];
                    Icu.GetSortKeyBound(sortKey,
                                        i < tokens.Length - 1
                                                                                                ? Icu.UColBoundMode.UCOL_BOUND_UPPER
                                                                                                : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper);
                    IEnumerable <T> items = index.GetItems(lower, upper);
                    results = results == null ? items : results.Intersect(items);
                }
                return(results);
            }

            return(Enumerable.Empty <T>());
        }
Пример #2
0
        /// <summary>
        /// Searches an index for the specified string.
        /// </summary>
        /// <param name="indexId">The index ID.</param>
        /// <param name="tss">The string.</param>
        /// <returns>The search results.</returns>
        public IEnumerable <T> Search(int indexId, ITsString tss)
        {
            if (tss == null || string.IsNullOrEmpty(tss.Text))
            {
                return(Enumerable.Empty <T>());
            }

            HashSet <T> results = null;

            foreach (Tuple <int, string> wsStr in GetWsStrings(tss))
            {
                SortKeyIndex index    = GetIndex(indexId, wsStr.Item1);
                ICollator    collator = m_wsManager.Get(wsStr.Item1).Collator;
                switch (m_type)
                {
                case SearchType.Exact:
                case SearchType.Prefix:
                {
                    byte[] sortKey = collator.GetSortKey(wsStr.Item2).KeyData;
                    var    lower   = new byte[wsStr.Item2.Length * SortKeyFactor];
                    Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower);
                    var upper = new byte[wsStr.Item2.Length * SortKeyFactor];
                    Icu.GetSortKeyBound(sortKey,
                                        m_type == SearchType.Exact
                                                                                                        ? Icu.UColBoundMode.UCOL_BOUND_UPPER
                                                                                                        : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper);
                    IEnumerable <T> items = index.GetItems(lower, upper);
                    if (results == null)
                    {
                        results = new HashSet <T>(items);
                    }
                    else
                    {
                        results.IntersectWith(items);
                    }
                    break;
                }

                case SearchType.FullText:
                    string   locale = m_wsManager.GetStrFromWs(wsStr.Item1);
                    string[] tokens = Icu.Split(Icu.UBreakIteratorType.UBRK_WORD, locale, wsStr.Item2).ToArray();
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        byte[] sortKey = collator.GetSortKey(tokens[i]).KeyData;
                        var    lower   = new byte[tokens[i].Length * SortKeyFactor];
                        Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower);
                        var upper = new byte[tokens[i].Length * SortKeyFactor];
                        Icu.GetSortKeyBound(sortKey,
                                            i < tokens.Length - 1
                                                                                                        ? Icu.UColBoundMode.UCOL_BOUND_UPPER
                                                                                                        : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper);
                        IEnumerable <T> items = index.GetItems(lower, upper);
                        if (results == null)
                        {
                            results = new HashSet <T>(items);
                        }
                        else
                        {
                            results.IntersectWith(items);
                        }
                    }
                    break;
                }
            }
            return(results ?? Enumerable.Empty <T>());
        }