| 5164 | |
| 5165 | |
| 5166 | static void garbage_collect(thread_db* tdbb, record_param* rpb, ULONG prior_page, RecordStack& staying) |
| 5167 | { |
| 5168 | /************************************** |
| 5169 | * |
| 5170 | * g a r b a g e _ c o l l e c t |
| 5171 | * |
| 5172 | ************************************** |
| 5173 | * |
| 5174 | * Functional description |
| 5175 | * Garbage collect a chain of back record. This is called from |
| 5176 | * "purge" and "expunge." One enters this routine with an |
| 5177 | * inactive record_param, describing a records which has either |
| 5178 | * 1) just been deleted or |
| 5179 | * 2) just had its back pointers set to zero |
| 5180 | * Therefor we can do a fetch on the back pointers we've got |
| 5181 | * because we have the last existing copy of them. |
| 5182 | * |
| 5183 | **************************************/ |
| 5184 | |
| 5185 | SET_TDBB(tdbb); |
| 5186 | |
| 5187 | #ifdef VIO_DEBUG |
| 5188 | jrd_rel* relation = rpb->rpb_relation; |
| 5189 | VIO_trace(DEBUG_WRITES, |
| 5190 | "garbage_collect (rel_id %u, record_param %" QUADFORMAT"d, prior_page %" SLONGFORMAT", staying)\n", |
| 5191 | relation->rel_id, rpb->rpb_number.getValue(), prior_page); |
| 5192 | |
| 5193 | VIO_trace(DEBUG_WRITES_INFO, |
| 5194 | " record %" SLONGFORMAT":%d, rpb_trans %" SQUADFORMAT |
| 5195 | ", flags %d, back %" SLONGFORMAT":%d, fragment %" SLONGFORMAT":%d\n", |
| 5196 | rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, |
| 5197 | rpb->rpb_flags, rpb->rpb_b_page, rpb->rpb_b_line, |
| 5198 | rpb->rpb_f_page, rpb->rpb_f_line); |
| 5199 | #endif |
| 5200 | |
| 5201 | RuntimeStatistics::Accumulator backversions(tdbb, rpb->rpb_relation, |
| 5202 | RuntimeStatistics::RECORD_BACKVERSION_READS); |
| 5203 | |
| 5204 | // Delete old versions fetching data for garbage collection. |
| 5205 | |
| 5206 | RecordStack going; |
| 5207 | |
| 5208 | while (rpb->rpb_b_page) |
| 5209 | { |
| 5210 | rpb->rpb_record = NULL; |
| 5211 | prior_page = rpb->rpb_page; |
| 5212 | rpb->rpb_page = rpb->rpb_b_page; |
| 5213 | rpb->rpb_line = rpb->rpb_b_line; |
| 5214 | |
| 5215 | if (!DPM_fetch(tdbb, rpb, LCK_write)) |
| 5216 | BUGCHECK(291); // msg 291 cannot find record back version |
| 5217 | |
| 5218 | delete_record(tdbb, rpb, prior_page, tdbb->getDefaultPool()); |
| 5219 | |
| 5220 | if (rpb->rpb_record) |
| 5221 | { |
| 5222 | rpb->rpb_record->setTransactionNumber(rpb->rpb_transaction_nr); |
| 5223 | going.push(rpb->rpb_record); |
no test coverage detected