Пример #1
0
        internal override IntArrayList GetMatchingResources(out bool sortedById)
        {
            lock (this)
            {
                if (_sourcePredicatesSelective == null)
                {
                    BuildSelectionPlan(_sourcePredicates);
                }

                sortedById = true;
                if (_sourcePredicatesSelective.Length == 0)
                {
                    return(new IntArrayList());
                }

                if (_traceIntersections)
                {
                    Debug.WriteLine("Intersection source predicate selective: " + _sourcePredicatesSelective [0]);
                }

                int          i = 1;
                object       syncObject;
                IntArrayList result = _sourcePredicatesSelective [0].GetSortedMatchingResourcesRef(out syncObject);
                if (syncObject != null)
                {
                    if (_sourcePredicatesSelective.Length == 1)
                    {
                        lock ( syncObject )
                        {
                            result = (IntArrayList)result.Clone();
                        }
                    }
                    else
                    {
                        i = 2;
                        object       syncObject2;
                        IntArrayList list2 = _sourcePredicatesSelective [1].GetSortedMatchingResourcesRef(out syncObject2);
                        using (new MultiLock(syncObject, syncObject2))
                        {
                            result = IntArrayList.IntersectSortedNew(result, list2);
                        }
                    }
                }

                for ( ; result.Count > 0 && i < _sourcePredicatesSelective.Length; i++)
                {
                    if (_traceIntersections)
                    {
                        Debug.WriteLine("Intersection source predicate selective: " + _sourcePredicatesSelective [i]);
                    }
                    IntArrayList list2 = _sourcePredicatesSelective [i].GetSortedMatchingResourcesRef(out syncObject);
                    MTSafeInPlaceIntersectSorted(syncObject, result, list2);
                }

                int skipIndex   = -1;
                int filterCount = _sourcePredicatesFiltering.Length;
                if (result.Count > 100 && filterCount > 0)
                {
                    filterCount--;
                    // If the first intersection predicate returned too many results, run the
                    // first filtering predicate as selection and intersect, instead of loading
                    // all the resources and checking filters
                    skipIndex = FindCheapestFilteringPredicate();
                    if (_traceIntersections)
                    {
                        Debug.WriteLine("Intersection cheapest filtering source: " + _sourcePredicatesFiltering [skipIndex]);
                    }
                    IntArrayList list2 = _sourcePredicatesFiltering [skipIndex].GetSortedMatchingResourcesRef(out syncObject);
                    MTSafeInPlaceIntersectSorted(syncObject, result, list2);
                }

                // filter the result by applying non-selective predicates
                if (result.Count > 0 && filterCount > 0)
                {
                    if (_traceIntersections)
                    {
                        for (i = 0; i < _sourcePredicatesFiltering.Length; i++)
                        {
                            Debug.WriteLine("Intersection source predicate filtering: " + _sourcePredicatesFiltering [i]);
                        }
                    }

                    int srcIndex = 0, destIndex = 0;
                    while (srcIndex < result.Count)
                    {
                        if (MatchFiltering(result [srcIndex], skipIndex))
                        {
                            result [destIndex] = result [srcIndex];
                            destIndex++;
                        }
                        srcIndex++;
                    }
                    result.RemoveRange(destIndex, result.Count - destIndex);
                }
                return(result);
            }
        }