Slideshow:
for ( each tuple s ∈ S ) do { for ( each tuple r ∈ R ) do { if ( r(Y) == s(Y) ) { output (r, s); } } } |
Worst case performance:
# Disk I/O = T(S) × T(R) |
Advantage:
|
|
Open( ) { R.Open( ); S.Open( ); s = S.getNext(); // s = current tuple of S } |
Graphically:
Note:
|
getNext( ) algorithm in pseudo code:
/* ------------------------------------------------------------------ getNext( ): output the next (1 !!!) tuple in the join R ⋈ S ----------------------------------------------------------------- */ getNext( ) { /* ============================================================== Note: At this point in the code, s contains the current tuple ∈ S ============================================================== */ while ( true ) { // Loop exits when: // 1. we found a tuple ∈ R that joins with s // 2. R ⋈ S is done (returns NotFound) /* ======================================================== (1) Get the next tuple r ∈ R (and try joining with s) ======================================================= */ r = R.getNext(); // Try to get next tuple in R /* ======================================================== (2) Check if R has reached the end of file: If R has ended: (A) get next tuple in S (B) Restart R from the beginning ======================================================= */ if ( r == NotFound ) { /* ========================================================= Tuple s has now joined with every tuple ∈ R (A) Use next tuple ∈ S in the join operation ========================================================= */ s = S.getNext( ); if ( s == NotFound ) { /* **************************************** We have processed the last tuple ∈ S: **************************************** */ return NotFound; // Done !!! } /* ================================================= The new tuple s ∈ S must join with all tuples in R (B) Restart R from the beginning ================================================= */ R.Close(); // Close first R.Open( ); // Reset R to beginning r = R.getNext(); // r = current tuple in R } /* ================================================= At this point in the code, we have: s = current tuple ∈ S for the Join operation r = current tuple ∈ R for the Join operation ================================================= */ /* ================================================= (2) Try to return next tuple in R ⋈ S ================================================ */ if ( r(Y) == s(Y) ) { return (r,s); // Return next tuple of Join } /* ================================================= r and s failed to join Repeat and try the next tuple in R (and if necessary get next tuple in S) ================================================= */ } } |
Close( ) { R.Close( ); S.Close( ); } |