* tbm_intersect - set intersection * * a is modified in-place, b is not changed */
| 561 | * a is modified in-place, b is not changed |
| 562 | */ |
| 563 | void |
| 564 | tbm_intersect(TIDBitmap *a, const TIDBitmap *b) |
| 565 | { |
| 566 | Assert(!a->iterating); |
| 567 | /* Nothing to do if a is empty */ |
| 568 | if (a->nentries == 0) |
| 569 | return; |
| 570 | |
| 571 | a->nentries_hwm = Max(a->nentries_hwm, a->nentries); |
| 572 | |
| 573 | /* Scan through chunks and pages in a, try to match to b */ |
| 574 | if (a->status == TBM_ONE_PAGE) |
| 575 | { |
| 576 | if (tbm_intersect_page(a, &a->entry1, b)) |
| 577 | { |
| 578 | /* Page is now empty, remove it from a */ |
| 579 | Assert(!a->entry1.ischunk); |
| 580 | a->npages--; |
| 581 | a->nentries--; |
| 582 | Assert(a->nentries == 0); |
| 583 | a->status = TBM_EMPTY; |
| 584 | } |
| 585 | } |
| 586 | else |
| 587 | { |
| 588 | pagetable_iterator i; |
| 589 | PagetableEntry *apage; |
| 590 | |
| 591 | Assert(a->status == TBM_HASH); |
| 592 | pagetable_start_iterate(a->pagetable, &i); |
| 593 | while ((apage = pagetable_iterate(a->pagetable, &i)) != NULL) |
| 594 | { |
| 595 | if (tbm_intersect_page(a, apage, b)) |
| 596 | { |
| 597 | /* Page or chunk is now empty, remove it from a */ |
| 598 | if (apage->ischunk) |
| 599 | a->nchunks--; |
| 600 | else |
| 601 | a->npages--; |
| 602 | a->nentries--; |
| 603 | if (!pagetable_delete(a->pagetable, apage->blockno)) |
| 604 | elog(ERROR, "hash table corrupted"); |
| 605 | } |
| 606 | } |
| 607 | } |
| 608 | } |
| 609 | |
| 610 | /* |
| 611 | * Process one page of a during an intersection op |
no test coverage detected