| 668 | |
| 669 | template <bool ignoreNullKeys> |
| 670 | void HashTable<ignoreNullKeys>::joinProbe(HashLookup& lookup) { |
| 671 | incrementProbes(lookup.rows.size()); |
| 672 | if (hashMode_ == HashMode::kArray) { |
| 673 | arrayJoinProbe(lookup); |
| 674 | return; |
| 675 | } |
| 676 | if (hashMode_ == HashMode::kNormalizedKey) { |
| 677 | populateNormalizedKeys(lookup, sizeBits_); |
| 678 | joinNormalizedKeyProbe(lookup); |
| 679 | return; |
| 680 | } |
| 681 | int32_t probeIndex = 0; |
| 682 | int32_t numProbes = lookup.rows.size(); |
| 683 | const vector_size_t* rows = lookup.rows.data(); |
| 684 | ProbeState state1; |
| 685 | ProbeState state2; |
| 686 | ProbeState state3; |
| 687 | ProbeState state4; |
| 688 | for (; probeIndex + 4 <= numProbes; probeIndex += 4) { |
| 689 | int32_t row = rows[probeIndex]; |
| 690 | state1.preProbe(*this, lookup.hashes[row], row); |
| 691 | row = rows[probeIndex + 1]; |
| 692 | state2.preProbe(*this, lookup.hashes[row], row); |
| 693 | row = rows[probeIndex + 2]; |
| 694 | state3.preProbe(*this, lookup.hashes[row], row); |
| 695 | row = rows[probeIndex + 3]; |
| 696 | state4.preProbe(*this, lookup.hashes[row], row); |
| 697 | state1.firstProbe(*this, 0); |
| 698 | state2.firstProbe(*this, 0); |
| 699 | state3.firstProbe(*this, 0); |
| 700 | state4.firstProbe(*this, 0); |
| 701 | fullProbe<true>(lookup, state1, false); |
| 702 | fullProbe<true>(lookup, state2, false); |
| 703 | fullProbe<true>(lookup, state3, false); |
| 704 | fullProbe<true>(lookup, state4, false); |
| 705 | } |
| 706 | for (; probeIndex < numProbes; ++probeIndex) { |
| 707 | int32_t row = rows[probeIndex]; |
| 708 | state1.preProbe(*this, lookup.hashes[row], row); |
| 709 | state1.firstProbe(*this, 0); |
| 710 | fullProbe<true>(lookup, state1, false); |
| 711 | } |
| 712 | } |
| 713 | |
| 714 | template <bool ignoreNullKeys> |
| 715 | void HashTable<ignoreNullKeys>::arrayGroupProbe(HashLookup& lookup) { |