| 2565 | } |
| 2566 | |
| 2567 | Validation::RTN Validation::walk_pointer_page(jrd_rel* relation, ULONG sequence) |
| 2568 | { |
| 2569 | /************************************** |
| 2570 | * |
| 2571 | * w a l k _ p o i n t e r _ p a g e |
| 2572 | * |
| 2573 | ************************************** |
| 2574 | * |
| 2575 | * Functional description |
| 2576 | * Walk a pointer page for a relation. Return rtn_ok if there are more to go. |
| 2577 | * |
| 2578 | **************************************/ |
| 2579 | Database* dbb = vdr_tdbb->getDatabase(); |
| 2580 | |
| 2581 | const vcl* vector = relation->getBasePages()->rel_pages; |
| 2582 | |
| 2583 | if (!vector || sequence >= vector->count()) |
| 2584 | return corrupt(VAL_P_PAGE_LOST, relation, sequence); |
| 2585 | |
| 2586 | pointer_page* page = 0; |
| 2587 | WIN window(DB_PAGE_SPACE, -1); |
| 2588 | window.win_flags = WIN_garbage_collector; |
| 2589 | |
| 2590 | fetch_page(true, (*vector)[sequence], pag_pointer, &window, &page); |
| 2591 | |
| 2592 | #ifdef DEBUG_VAL_VERBOSE |
| 2593 | if (VAL_debug_level) |
| 2594 | { |
| 2595 | fprintf(stdout, "walk_pointer_page: page %d relation %d sequence %d\n", |
| 2596 | (*vector)[sequence], relation->rel_id, sequence); |
| 2597 | } |
| 2598 | #endif |
| 2599 | |
| 2600 | // Give the page a quick once over |
| 2601 | |
| 2602 | if (page->ppg_relation != relation->rel_id || page->ppg_sequence != sequence) |
| 2603 | { |
| 2604 | release_page(&window); |
| 2605 | return corrupt(VAL_P_PAGE_INCONSISTENT, relation, (*vector)[sequence], sequence); |
| 2606 | } |
| 2607 | |
| 2608 | // Walk the data pages (someday we may optionally walk pages with "large objects" |
| 2609 | |
| 2610 | ULONG seq = sequence * dbb->dbb_dp_per_pp; |
| 2611 | UCHAR* bits = (UCHAR*) (page->ppg_page + dbb->dbb_dp_per_pp); |
| 2612 | bool marked = false; |
| 2613 | USHORT slot = 0; |
| 2614 | for (ULONG* pages = page->ppg_page; slot < page->ppg_count; slot++, pages++, seq++) |
| 2615 | { |
| 2616 | if (*pages) |
| 2617 | { |
| 2618 | UCHAR new_pp_bits = 0; |
| 2619 | |
| 2620 | // If walk_data_page() below going to evaluate conditions expressions, |
| 2621 | // pointer page should be released to avoid deadlocks. |
| 2622 | |
| 2623 | const bool releasePP = vdr_cond_idx.hasData(); |
| 2624 | if (releasePP) |
nothing calls this directly
no test coverage detected