示例#1
0
 public override void UnlockRoot(int lockKey)
 {
     // We unlock the reference table.
     // NOTE: This cause the reference table to unlock twice when we use the
     //  'MergeWithReference' method.  While this isn't perfect behaviour, it
     //  means if 'MergeWithReference' isn't used, we still maintain a safe
     //  level of locking.
     ReferenceTable.UnlockRoot(lockKey);
 }
示例#2
0
        // ------ Public methods ------

        ///<summary>
        /// Sets the whole reference table as a single group.
        ///</summary>
        public void SetWholeTableAsGroup()
        {
            wholeTableAsGroup = true;

            wholeTableGroupSize = ReferenceTable.RowCount;

            // Set up 'whole_table_group' to the list of all rows in the reference
            // table.
            IEnumerator <long> en = ReferenceTable.GetRowEnumerator();

            wholeTableIsSimpleEnum = en is SimpleRowEnumerator;
            if (!wholeTableIsSimpleEnum)
            {
                wholeTableGroup = new List <long>((int)ReferenceTable.RowCount);
                while (en.MoveNext())
                {
                    wholeTableGroup.Add(en.Current);
                }
            }

            // Set up a group resolver for this method.
            groupResolver = new TableGroupResolver(this);
        }
示例#3
0
        ///<summary>
        /// Returns a Table that is this function table merged with the cross
        /// reference table.
        ///</summary>
        ///<param name="maxColumn"></param>
        /// <remarks>
        /// The result table includes only one row from each group.
        /// <para>
        /// The 'max_column' argument is optional (can be null).  If it's set to a
        /// column in the reference table, then the row with the max value from the
        /// group is used as the group row.  For example, 'Part.id' will return the
        /// row with the maximum part.id from each group.
        /// </para>
        /// </remarks>
        ///<returns></returns>
        public Table MergeWithReference(ObjectName maxColumn)
        {
            Table table = ReferenceTable;

            IList <long> rowList;

            if (wholeTableAsGroup)
            {
                // Whole table is group, so take top entry of table.

                rowList = new List <long>(1);
                IEnumerator <long> rowEnum = table.GetRowEnumerator();
                if (rowEnum.MoveNext())
                {
                    rowList.Add(rowEnum.Current);
                }
                else
                {
                    // MAJOR HACK: If the referencing table has no elements then we choose
                    //   an arbitary index from the reference table to merge so we have
                    //   at least one element in the table.
                    //   This is to fix the 'SELECT COUNT(*) FROM empty_table' bug.
                    rowList.Add(Int32.MaxValue - 1);
                }
            }
            else if (table.RowCount == 0)
            {
                rowList = new List <long>(0);
            }
            else if (groupLinks != null)
            {
                // If we are grouping, reduce down to only include one row from each
                // group.
                if (maxColumn == null)
                {
                    rowList = GetTopFromEachGroup();
                }
                else
                {
                    int col_num = ReferenceTable.FindFieldName(maxColumn);
                    rowList = GetMaxFromEachGroup(col_num);
                }
            }
            else
            {
                // OPTIMIZATION: This should be optimized.  It should be fairly trivial
                //   to generate a Table implementation that efficiently merges this
                //   function table with the reference table.

                // This means there is no grouping, so merge with entire table,
                long rowCount = table.RowCount;
                rowList = new List <long>((int)rowCount);
                IEnumerator <long> en = table.GetRowEnumerator();
                while (en.MoveNext())
                {
                    rowList.Add(en.Current);
                }
            }

            // Create a virtual table that's the new group table merged with the
            // functions in this...

            Table[]        tabs    = new Table[] { table, this };
            IList <long>[] rowSets = new IList <long>[] { rowList, rowList };

            VirtualTable outTable = new VirtualTable(tabs);

            outTable.Set(tabs, rowSets);
            table = outTable;
            return(table);
        }