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( ); } |
|
|