Exemple #1
0
                public override void Invoke(SpoolSpace Memory)
                {
                    // Add spools //
                    this.AddSpools(Memory);

                    // Render each table //
                    Table  ltable = (this._Parameters[0]).Select(Memory);
                    Table  rtable = (this._Parameters[1]).Select(Memory);
                    string lalias = this._Parameters[0].NameOf();
                    string ralias = this._Parameters[1].NameOf();

                    // Get the left and right join index //
                    TreeIndex lidx = ltable.GetIndex(this._LKey) ?? TreeIndex.BuildTemporaryIndex(ltable, this._LKey);
                    //lidx.Tree.DumpMeta(@"C:\Users\pwdlu_000\Documents\Spectre_Projects\Test\treeJoinT1.txt");
                    TreeIndex ridx = rtable.GetIndex(this._RKey) ?? TreeIndex.BuildTemporaryIndex(rtable, this._RKey);

                    // Get the join tags //
                    bool Intersection = (this._Affinity == JoinAffinity.Inner || this._Affinity == JoinAffinity.Left);
                    bool Antisection  = (this._Affinity == JoinAffinity.Left || this._Affinity == JoinAffinity.AntiLeft);

                    // Open a read stream //
                    RecordReader lstream = lidx.OpenReader();
                    RecordReader rstream = ridx.OpenReader();

                    // Render some null records //
                    Record RNull = rstream.Columns.NullRecord;

                    // Main loop through both left and right
                    while (lstream.CanAdvance && rstream.CanAdvance)
                    {
                        Record lrec    = lstream.Read();
                        Record rrec    = rstream.Read();
                        int    Compare = Record.Compare(lrec, this._LKey, rrec, this._RKey);

                        // Left is less than right, control left
                        if (Compare < 0)
                        {
                            lstream.Advance();
                        }
                        // AWValue is less than left, control right, but also output an anti join record
                        else if (Compare > 0)
                        {
                            if (Antisection)
                            {
                                Memory[lalias].Set(lrec);
                                Memory[ralias].Set(RNull);
                                if (this._Filter.Evaluate(Memory))
                                {
                                    this.InvokeChildren(Memory);
                                }
                            }
                            rstream.Advance();
                        }
                        else if (Intersection) // Compare == 0
                        {
                            // Save the loop-result //
                            int NestedLoopCount = 0;

                            // Loop through all possible tuples //
                            while (Compare == 0)
                            {
                                // Render the record and potentially output //
                                Memory[lalias].Set(lstream.Read());
                                Memory[ralias].Set(rstream.Read());
                                if (this._Filter.Evaluate(Memory))
                                {
                                    this.InvokeChildren(Memory);
                                }

                                // Advance the right table //
                                rstream.Advance();
                                NestedLoopCount++;

                                // Check if this advancing pushed us to the end of the table //
                                if (!rstream.CanAdvance)
                                {
                                    break;
                                }

                                // Reset the compare token //
                                Compare = Record.Compare(lstream.Read(), this._LKey, rstream.Read(), this._RKey);
                            }

                            // Revert the nested loops //
                            rstream.Revert(NestedLoopCount);

                            // Step the left stream //
                            lstream.Advance();
                        }
                        else
                        {
                            lstream.Advance();
                        }
                    }

                    // Do Anti-Join //
                    if (Antisection)
                    {
                        // Assign the right table to null //
                        Memory[ralias].Set(RNull);

                        // Walk the rest of the left table //
                        while (lstream.CanAdvance)
                        {
                            Memory[lalias].Set(lstream.ReadNext());
                            if (this._Filter.Evaluate(Memory))
                            {
                                this.InvokeChildren(Memory);
                            }
                        }
                    }

                    // Add spools //
                    this.RemoveSpools(Memory);
                }