MCPcopy Create free account
hub / github.com/apache/impala / BuildHashTable

Method BuildHashTable

be/src/exec/partitioned-hash-join-builder.cc:1218–1303  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1216}
1217
1218Status PhjBuilderPartition::BuildHashTable(bool* built) {
1219 SCOPED_TIMER(parent_->build_hash_table_timer_);
1220 DCHECK(build_rows_ != nullptr);
1221 *built = false;
1222
1223 // Before building the hash table, we need to pin the rows in memory.
1224 RETURN_IF_ERROR(build_rows_->PinStream(built));
1225 if (!*built) return Status::OK();
1226
1227 RuntimeState* state = parent_->runtime_state_;
1228 HashTableCtx* ctx = parent_->ht_ctx_.get();
1229 ctx->set_level(level()); // Set the hash function for building the hash table.
1230 RowBatch batch(parent_->row_desc_, state->batch_size(), parent_->mem_tracker());
1231 vector<BufferedTupleStream::FlatRowPtr> flat_rows;
1232 bool eos = false;
1233
1234 // Allocate the partition-local hash table. Initialize the number of buckets based on
1235 // the number of build rows (the number of rows is known at this point). This assumes
1236 // there are no duplicates which can be wrong. However, the upside in the common case
1237 // (few/no duplicates) is large and the downside when there are is low (a bit more
1238 // memory; the bucket memory is small compared to the memory needed for all the build
1239 // side allocations).
1240 // One corner case is if the stream contains tuples with zero footprint (no materialized
1241 // slots). If the tuples occupy no space, this implies all rows will be duplicates, so
1242 // create a small hash table, IMPALA-2256.
1243 //
1244 // TODO: Try to allocate the hash table before pinning the stream to avoid needlessly
1245 // reading all of the spilled rows from disk when we won't succeed anyway.
1246 int64_t estimated_num_buckets = HashTable::EstimateNumBuckets(build_rows()->num_rows());
1247 hash_tbl_.reset(HashTable::Create(parent_->ht_allocator_.get(),
1248 true /* store_duplicates */, parent_->row_desc_->tuple_descriptors().size(),
1249 build_rows(), 1 << (32 - PhjBuilder::NUM_PARTITIONING_BITS),
1250 estimated_num_buckets));
1251 bool success;
1252 Status status = hash_tbl_->Init(&success);
1253 if (!status.ok() || !success) goto not_built;
1254 status = build_rows_->PrepareForRead(false, &success);
1255 if (!status.ok()) goto not_built;
1256 DCHECK(success) << "Stream was already pinned.";
1257
1258 do {
1259 status = build_rows_->GetNext(&batch, &eos, &flat_rows);
1260 if (!status.ok()) goto not_built;
1261 DCHECK_EQ(batch.num_rows(), flat_rows.size());
1262 DCHECK_LE(batch.num_rows(), hash_tbl_->EmptyBuckets());
1263 TPrefetchMode::type prefetch_mode = state->query_options().prefetch_mode;
1264
1265 InsertBatchFn insert_batch_fn;
1266 if (level() == 0) {
1267 insert_batch_fn = parent_->insert_batch_fn_level0_.load();
1268 } else {
1269 insert_batch_fn = parent_->insert_batch_fn_.load();
1270 }
1271
1272 if (insert_batch_fn != nullptr) {
1273 if (UNLIKELY(
1274 !insert_batch_fn(this, prefetch_mode, ctx, &batch, flat_rows, &status))) {
1275 goto not_built;

Calls 15

OKFunction · 0.85
CreateClass · 0.85
PinStreamMethod · 0.80
set_levelMethod · 0.80
batch_sizeMethod · 0.80
EmptyBucketsMethod · 0.80
num_bucketsMethod · 0.80
getMethod · 0.65
resetMethod · 0.65
mem_trackerMethod · 0.45
num_rowsMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected