Slideshow:
|
|
|
|
|
|
|
I.e.:
|
Open( )
{
Open target relation R;
b = allocate 1 block buffer space;
b = read first block of R; // Prepare for getNext( )
t = address of first tuple in block b; // Prepare to return next tuple
}
|
getNext( )
{
/* ==============================================================
Make sure t points to a valide tuple before proceeding
============================================================== */
if ( tuple t has passed the last tuple in block b )
{
/* -------------------------------------------------
Re-position t to be the first tuple of next block
------------------------------------------------- */
Read the next block into b;
if ( there is no next block )
{
return NotFound;
}
else
{
t = first tuple in block b;
}
}
/* ===========================================
Here: t points to a valid next tuple
=========================================== */
curr_t = t; // Save the return value
increment t to the next tuple in block b;
return curr_t;
}
|
Close( )
{
free buffer b;
close file;
}
|
|
The implementation of BagUnion will illustrate the pipelining effect :
|
ScanTable R, S = input relations to BagUnion
Open( )
{
R.Open(); // This will call the Open() method in ScanTable !!!
CurrRel = R;
}
|
getNext()
{
if ( currRel == R )
{
t = R.getNext(); // Call ScanTable to get next tuple
if ( t ≠ NotFound )
{
/* ------------------------------
We read a valid tuple from R
------------------------------ */
return t;
}
else
{
/* ===========================
R is done, we read S next
=========================== */
S.Open(); // Call ScanTable's Open()
currRel = S; // Make this if-statement stop executing
}
}
/* =============================================
We will only reach here if R is exhausted...
============================================= */
return S.getNext();
}
|
Close( )
{
R.Close( );
S.Close( );
}
|
|
|