Example #1
0
        public static IList <long> In(this ITable table, ITable table2, int column1, int column2)
        {
            // First pick the the smallest and largest table.  We only want to iterate
            // through the smallest table.
            // NOTE: This optimisation can't be performed for the 'not_in' command.

            ITable smallTable;
            ITable largeTable;
            int    smallColumn;
            int    largeColumn;

            if (table.RowCount < table2.RowCount)
            {
                smallTable = table;
                largeTable = table2;

                smallColumn = column1;
                largeColumn = column2;
            }
            else
            {
                smallTable = table2;
                largeTable = table;

                smallColumn = column2;
                largeColumn = column1;
            }

            // Iterate through the small table's column.  If we can find identical
            // cells in the large table's column, then we should include the row in our
            // final result.

            BlockIndex <long>  resultRows = new BlockIndex <long>();
            IEnumerator <long> e          = smallTable.GetRowEnumerator();
            Operator           op         = Operator.Equal;

            while (e.MoveNext())
            {
                long       smallRowIndex = e.Current;
                DataObject cell          = smallTable.GetValue(smallColumn, smallRowIndex);

                IEnumerable <long> selectedSet = largeTable.SelectRows(largeColumn, op, cell);

                // We've found cells that are IN both columns,

                if (selectedSet.Any())
                {
                    // If the large table is what our result table will be based on, append
                    // the rows selected to our result set.  Otherwise add the index of
                    // our small table.  This only works because we are performing an
                    // EQUALS operation.

                    if (largeTable == table)
                    {
                        // Only allow unique rows into the table set.
                        foreach (var set in selectedSet)
                        {
                            if (!resultRows.UniqueInsertSort((int)set))
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        // Don't bother adding in sorted order because it's not important.
                        resultRows.Add((int)smallRowIndex);
                    }
                }
            }

            return(resultRows.Cast <long>().ToList());
        }