This function makes linear stacks lookup. Therefore in case of big stacks garbage collection speed may become real problem. Stacks should be sorted before run? 2006.03.17 hvlad: it is sorted now
| 423 | // real problem. Stacks should be sorted before run? |
| 424 | // 2006.03.17 hvlad: it is sorted now |
| 425 | void BLB_garbage_collect(thread_db* tdbb, |
| 426 | RecordStack& going, |
| 427 | RecordStack& staying, |
| 428 | ULONG prior_page, jrd_rel* relation) |
| 429 | { |
| 430 | /************************************** |
| 431 | * |
| 432 | * B L B _ g a r b a g e _ c o l l e c t |
| 433 | * |
| 434 | ************************************** |
| 435 | * |
| 436 | * Functional description |
| 437 | * Garbage collect indices and blobs. Garbage_collect is passed a |
| 438 | * stack of record blocks of records that are being deleted and a stack |
| 439 | * of records blocks of records that are staying. Garbage_collect |
| 440 | * can be called from four operations: |
| 441 | * |
| 442 | * VIO_backout -- removing top record |
| 443 | * expunge -- removing all versions of a record |
| 444 | * purge -- removing all but top version of a record |
| 445 | * update_in_place -- replace the top level record. |
| 446 | * |
| 447 | * hvlad: note that same blob_id can be reused by the staying record version |
| 448 | * in the different field than it was in going record. This is happening |
| 449 | * with 3 blob fields and update_in_place |
| 450 | * |
| 451 | **************************************/ |
| 452 | SET_TDBB(tdbb); |
| 453 | |
| 454 | fb_assert(prior_page > 0); |
| 455 | RecordBitmap bmGoing; |
| 456 | ULONG cntGoing = 0; |
| 457 | |
| 458 | // Loop thru records on the way out looking for blobs to garbage collect |
| 459 | for (RecordStack::iterator stack1(going); stack1.hasData(); ++stack1) |
| 460 | { |
| 461 | Record* rec = stack1.object(); |
| 462 | if (!rec) |
| 463 | continue; |
| 464 | |
| 465 | // Look for active blob records |
| 466 | const Format* format = rec->getFormat(); |
| 467 | for (USHORT id = 0; id < format->fmt_count; id++) |
| 468 | { |
| 469 | DSC desc; |
| 470 | if (DTYPE_IS_BLOB(format->fmt_desc[id].dsc_dtype) && EVL_field(0, rec, id, &desc)) |
| 471 | { |
| 472 | const bid* blob = (bid*) desc.dsc_address; |
| 473 | if (!blob->isEmpty()) |
| 474 | { |
| 475 | if (blob->bid_internal.bid_relation_id == relation->rel_id) |
| 476 | { |
| 477 | const RecordNumber number = blob->get_permanent_number(); |
| 478 | bmGoing.set(number.getValue()); |
| 479 | cntGoing++; |
| 480 | } |
| 481 | else |
| 482 | { |
no test coverage detected