* Construct an empty TupleHashTable * * numCols, keyColIdx: identify the tuple fields to use as lookup key * eqfunctions: equality comparison functions to use * hashfunctions: datatype-specific hashing functions to use * nbuckets: initial estimate of hashtable size * additionalsize: size of data stored in ->additional * metacxt: memory context for long-lived allocation, but not per-entry da
| 153 | * storage that will live as long as the hashtable does. |
| 154 | */ |
| 155 | TupleHashTable |
| 156 | BuildTupleHashTableExt(PlanState *parent, |
| 157 | TupleDesc inputDesc, |
| 158 | int numCols, AttrNumber *keyColIdx, |
| 159 | const Oid *eqfuncoids, |
| 160 | FmgrInfo *hashfunctions, |
| 161 | Oid *collations, |
| 162 | long nbuckets, Size additionalsize, |
| 163 | MemoryContext metacxt, |
| 164 | MemoryContext tablecxt, |
| 165 | MemoryContext tempcxt, |
| 166 | bool use_variable_hash_iv) |
| 167 | { |
| 168 | TupleHashTable hashtable; |
| 169 | Size entrysize = sizeof(TupleHashEntryData) + additionalsize; |
| 170 | Size hash_mem_limit; |
| 171 | MemoryContext oldcontext; |
| 172 | bool allow_jit; |
| 173 | |
| 174 | /* |
| 175 | * Many callers pass "long" values for nbuckets, which means that we can |
| 176 | * receive a bogus value on 64-bit machines. It seems unwise to change |
| 177 | * this function's signature in released branches, so instead assume that |
| 178 | * a negative input means long->int overflow occurred. |
| 179 | */ |
| 180 | if (nbuckets <= 0) |
| 181 | nbuckets = INT_MAX; |
| 182 | |
| 183 | Assert(nbuckets > 0); |
| 184 | |
| 185 | /* Limit initial table size request to not more than hash_mem */ |
| 186 | hash_mem_limit = get_hash_memory_limit() / entrysize; |
| 187 | if (nbuckets > hash_mem_limit) |
| 188 | nbuckets = hash_mem_limit; |
| 189 | |
| 190 | oldcontext = MemoryContextSwitchTo(metacxt); |
| 191 | |
| 192 | hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData)); |
| 193 | |
| 194 | hashtable->numCols = numCols; |
| 195 | hashtable->keyColIdx = keyColIdx; |
| 196 | hashtable->tab_hash_funcs = hashfunctions; |
| 197 | hashtable->tab_collations = collations; |
| 198 | hashtable->tablecxt = tablecxt; |
| 199 | hashtable->tempcxt = tempcxt; |
| 200 | hashtable->entrysize = entrysize; |
| 201 | hashtable->tableslot = NULL; /* will be made on first lookup */ |
| 202 | hashtable->inputslot = NULL; |
| 203 | hashtable->in_hash_funcs = NULL; |
| 204 | hashtable->cur_eq_func = NULL; |
| 205 | |
| 206 | /* |
| 207 | * If parallelism is in use, even if the leader backend is performing the |
| 208 | * scan itself, we don't want to create the hashtable exactly the same way |
| 209 | * in all workers. As hashtables are iterated over in keyspace-order, |
| 210 | * doing so in all processes in the same way is likely to lead to |
| 211 | * "unbalanced" hashtables when the table size initially is |
| 212 | * underestimated. |
no test coverage detected