| 465 | } |
| 466 | |
| 467 | SLONG MergeJoin::getRecordByIndex(thread_db* tdbb, FB_SIZE_T index) const |
| 468 | { |
| 469 | Request* const request = tdbb->getRequest(); |
| 470 | Impure* const impure = request->getImpure<Impure>(m_impure); |
| 471 | |
| 472 | const SortedStream* const sort_rsb = m_args[index]; |
| 473 | Impure::irsb_mrg_repeat* const tail = &impure->irsb_mrg_rpt[index]; |
| 474 | |
| 475 | const UCHAR* sort_data = sort_rsb->getData(tdbb); |
| 476 | if (!sort_data) |
| 477 | return -1; |
| 478 | |
| 479 | MergeFile* const mfb = &tail->irsb_mrg_file; |
| 480 | const SLONG record = mfb->mfb_equal_records; |
| 481 | |
| 482 | const ULONG merge_block = record / mfb->mfb_blocking_factor; |
| 483 | if (merge_block != mfb->mfb_current_block) |
| 484 | { |
| 485 | if (!mfb->mfb_space) |
| 486 | { |
| 487 | MemoryPool& pool = *getDefaultMemoryPool(); |
| 488 | mfb->mfb_space = FB_NEW_POOL(pool) TempSpace(pool, SCRATCH, false); |
| 489 | } |
| 490 | |
| 491 | Sort::writeBlock(mfb->mfb_space, mfb->mfb_block_size * mfb->mfb_current_block, |
| 492 | mfb->mfb_block_data, mfb->mfb_block_size); |
| 493 | mfb->mfb_current_block = merge_block; |
| 494 | } |
| 495 | |
| 496 | const ULONG merge_offset = (record % mfb->mfb_blocking_factor) * mfb->mfb_record_size; |
| 497 | UCHAR* merge_data = mfb->mfb_block_data + merge_offset; |
| 498 | |
| 499 | memcpy(merge_data, sort_data, sort_rsb->getLength()); |
| 500 | ++mfb->mfb_equal_records; |
| 501 | |
| 502 | return record; |
| 503 | } |
| 504 | |
| 505 | bool MergeJoin::fetchRecord(thread_db* tdbb, FB_SIZE_T index) const |
| 506 | { |
nothing calls this directly
no test coverage detected