| 1816 | |
| 1817 | template <bool ignoreNullKeys> |
| 1818 | void HashTable<ignoreNullKeys>::prepareJoinTable( |
| 1819 | std::vector<std::unique_ptr<BaseHashTable>> tables, |
| 1820 | folly::Executor* executor, |
| 1821 | bool dropDuplicates, |
| 1822 | int8_t spillInputStartPartitionBit) { |
| 1823 | buildExecutor_ = executor; |
| 1824 | if (dropDuplicates) { |
| 1825 | if (table_ != nullptr) { |
| 1826 | // Set table_ to nullptr to trigger rehash. |
| 1827 | rows_->pool()->freeContiguous(tableAllocation_); |
| 1828 | table_ = nullptr; |
| 1829 | capacity_ = 0; |
| 1830 | numDistinct_ = rows()->numRows(); |
| 1831 | } |
| 1832 | // Call analyze to insert all unique values in row container to the |
| 1833 | // table hashers' uniqueValues_; |
| 1834 | bool analyzeValue = !analyze(); |
| 1835 | if (analyzeValue) { |
| 1836 | if (hashMode_ != HashMode::kHash) { |
| 1837 | setHashMode(HashMode::kHash, 0); |
| 1838 | } else { |
| 1839 | checkSize(0, true); |
| 1840 | } |
| 1841 | } |
| 1842 | } |
| 1843 | |
| 1844 | otherTables_.reserve(tables.size()); |
| 1845 | for (auto& table : tables) { |
| 1846 | otherTables_.emplace_back(std::unique_ptr<HashTable<ignoreNullKeys>>( |
| 1847 | dynamic_cast<HashTable<ignoreNullKeys>*>(table.release()))); |
| 1848 | } |
| 1849 | |
| 1850 | // For hybrid mode |
| 1851 | if (hybridData_) { |
| 1852 | std::unordered_map<uint8_t, HybridContainer*> hybridDataChannel; |
| 1853 | hybridDataChannel[hybridData_->getId()] = hybridData_.get(); |
| 1854 | for (auto& table : otherTables_) |
| 1855 | hybridDataChannel[table->hybridData()->getId()] = table->hybridData(); |
| 1856 | hybridData_->setAllContainers(hybridDataChannel); |
| 1857 | } |
| 1858 | |
| 1859 | bool useValueIds = mayUseValueIds(*this); |
| 1860 | if (useValueIds) { |
| 1861 | for (auto& other : otherTables_) { |
| 1862 | if (!mayUseValueIds(*other)) { |
| 1863 | useValueIds = false; |
| 1864 | break; |
| 1865 | } |
| 1866 | } |
| 1867 | if (useValueIds) { |
| 1868 | for (auto& other : otherTables_) { |
| 1869 | if (dropDuplicates) { |
| 1870 | // Before merging with the current hashers, all values in the row |
| 1871 | // containers of other table need to be inserted into uniqueValues_. |
| 1872 | if (!other->analyze()) { |
| 1873 | other->setHashMode(HashMode::kHash, 0); |
| 1874 | useValueIds = false; |
| 1875 | break; |