public override Array GetUniqueValuesFromColumn()

in Arriba/Arriba/Model/Query/DistinctQuery.cs [179:306]


            public override Array GetUniqueValuesFromColumn(IColumn column, ShortSet whereSet, int count, out bool allValuesReturned)
            {
                if (count <= 0)
                {
                    allValuesReturned = false;
                    return new T[0];
                }

                IColumn<T> typedColumn = (IColumn<T>)column;

                // Boolean columns aren't sorted - just check true and false
                if (typedColumn is BooleanColumn)
                {
                    int countBefore = whereSet.Count();
                    if (countBefore == 0)
                    {
                        allValuesReturned = true;
                        return new bool[0];
                    }

                    // Filter to the set of values with the column 'true'
                    BooleanColumn bc = (BooleanColumn)typedColumn;
                    ShortSet trueSet = new ShortSet(bc.Count);
                    bc.TryWhere(Operator.Equals, true, trueSet, null);
                    whereSet.And(trueSet);

                    // Determine the count which were true and false matching the query
                    int countWhichAreTrue = whereSet.Count();
                    int countWhichAreFalse = countBefore - countWhichAreTrue;

                    allValuesReturned = true;

                    if (countWhichAreTrue > 0 && countWhichAreFalse > 0)
                    {
                        // If both existed and only one value was requested, return the value which more items had
                        if (count == 1)
                        {
                            allValuesReturned = false;
                            return new bool[] { (countWhichAreTrue > countWhichAreFalse) };
                        }

                        return new bool[] { true, false };
                    }
                    else if (countWhichAreTrue > 0)
                    {
                        return new bool[] { true };
                    }
                    else
                    {
                        return new bool[] { false };
                    }
                }

                // Get all LIDs in sorted order
                IList<ushort> sortedIndexes;
                int sortedIndexesCount;
                if (!column.TryGetSortedIndexes(out sortedIndexes, out sortedIndexesCount)) throw new ArribaException(String.Format("Unable to sort by non-sorted column {0}", column.Name));

                int uniqueValuesCount = 0;
                T prevValue = default(T);

                // Count the # of unique items
                for (int lastSortedIndex = 0; lastSortedIndex < sortedIndexesCount; ++lastSortedIndex)
                {
                    ushort itemLID = sortedIndexes[lastSortedIndex];

                    // Find the next LID which is still in our match set
                    if (whereSet.Contains(itemLID))
                    {
                        T currentValue = typedColumn[itemLID];

                        bool sameValue = prevValue.Equals(currentValue);

                        if (uniqueValuesCount != 0 && sameValue == true)
                        {
                            continue;
                        }

                        uniqueValuesCount++;
                        prevValue = currentValue;

                        // If we have enough matches, stop 
                        // (*after computing remaining items to tell if we got all of them*)
                        if (uniqueValuesCount == count)
                        {
                            break;
                        }
                    }
                }

                T[] uniqueValues = new T[uniqueValuesCount];
                ushort uniqueValuesIndex = 0;
                allValuesReturned = true;       // until proven false

                // Retrieve all of the unique items
                for (int lastSortedIndex = 0; lastSortedIndex < sortedIndexesCount; ++lastSortedIndex)
                {
                    ushort itemLID = sortedIndexes[lastSortedIndex];

                    // Find the next LID which is still in our match set
                    if (whereSet.Contains(itemLID))
                    {
                        T currentValue = typedColumn[itemLID];

                        bool sameValue = prevValue.Equals(currentValue);

                        if (uniqueValuesIndex != 0 && sameValue == true)
                        {
                            continue;
                        }

                        uniqueValues[uniqueValuesIndex++] = currentValue;
                        prevValue = currentValue;

                        // If we have enough matches, stop 
                        // (*after computing remaining items to tell if we got all of them*)
                        if (uniqueValuesIndex == count)
                        {
                            ushort lastItemLID = sortedIndexes[sortedIndexesCount - 1];
                            T lastValue = typedColumn[lastItemLID];
                            allValuesReturned = currentValue.Equals(lastValue);
                            break;
                        }
                    }
                }

                return uniqueValues;
            }