This test inserts and probes as many elements as the size of the hash table without calling resize. All the inserts and probes are expected to succeed, because there is enough space in the hash table (it is also expected to be slow). It also expects that a probe for a N+1 element will return BUCKET_NOT_FOUND.
| 554 | // enough space in the hash table (it is also expected to be slow). It also expects that |
| 555 | // a probe for a N+1 element will return BUCKET_NOT_FOUND. |
| 556 | void InsertFullTest(bool quadratic, int table_size) { |
| 557 | HashTable* hash_table; |
| 558 | ASSERT_TRUE(CreateHashTable(quadratic, table_size, &hash_table)); |
| 559 | EXPECT_EQ(hash_table->EmptyBuckets(), table_size); |
| 560 | scoped_ptr<HashTableCtx> ht_ctx; |
| 561 | Status status = HashTableCtx::Create(&pool_, runtime_state_, build_exprs_, |
| 562 | probe_exprs_, false /* !stores_nulls_ */, |
| 563 | vector<bool>(build_exprs_.size(), false), 1, 0, 1, &mem_pool_, |
| 564 | &mem_pool_, &mem_pool_, &ht_ctx); |
| 565 | EXPECT_OK(status); |
| 566 | |
| 567 | // Insert and probe table_size different tuples. All of them are expected to be |
| 568 | // successfully inserted and probed. |
| 569 | uint32_t hash = 0; |
| 570 | HashTable::Iterator iter; |
| 571 | bool found; |
| 572 | for (int build_row_val = 0; build_row_val < table_size; ++build_row_val) { |
| 573 | TupleRow* row = CreateTupleRow(build_row_val); |
| 574 | bool passes = ht_ctx->EvalAndHashBuild(row); |
| 575 | hash = ht_ctx->expr_values_cache()->CurExprValuesHash(); |
| 576 | EXPECT_TRUE(passes); |
| 577 | |
| 578 | // Insert using both Insert() and FindBucket() methods. |
| 579 | if (build_row_val % 2 == 0) { |
| 580 | BufferedTupleStream::FlatRowPtr dummy_flat_row = nullptr; |
| 581 | EXPECT_TRUE(hash_table->stores_tuples_); |
| 582 | bool inserted = hash_table->Insert(ht_ctx.get(), dummy_flat_row, row, &status); |
| 583 | EXPECT_TRUE(inserted); |
| 584 | ASSERT_OK(status); |
| 585 | } else { |
| 586 | iter = hash_table->FindBuildRowBucket(ht_ctx.get(), &found); |
| 587 | EXPECT_FALSE(iter.AtEnd()); |
| 588 | EXPECT_FALSE(found); |
| 589 | iter.SetTuple(row->GetTuple(0), hash); |
| 590 | } |
| 591 | EXPECT_EQ(hash_table->EmptyBuckets(), table_size - build_row_val - 1); |
| 592 | |
| 593 | passes = ht_ctx->EvalAndHashProbe(row); |
| 594 | (void)ht_ctx->expr_values_cache()->CurExprValuesHash(); |
| 595 | EXPECT_TRUE(passes); |
| 596 | iter = hash_table->FindProbeRow(ht_ctx.get()); |
| 597 | EXPECT_FALSE(iter.AtEnd()); |
| 598 | EXPECT_EQ(row->GetTuple(0), iter.GetTuple()); |
| 599 | |
| 600 | iter = hash_table->FindBuildRowBucket(ht_ctx.get(), &found); |
| 601 | EXPECT_FALSE(iter.AtEnd()); |
| 602 | EXPECT_TRUE(found); |
| 603 | EXPECT_EQ(row->GetTuple(0), iter.GetTuple()); |
| 604 | } |
| 605 | |
| 606 | // Probe for a tuple that does not exist. This should exercise the probe of a full |
| 607 | // hash table code path. |
| 608 | EXPECT_EQ(hash_table->EmptyBuckets(), 0); |
| 609 | TupleRow* probe_row = CreateTupleRow(table_size); |
| 610 | bool passes = ht_ctx->EvalAndHashProbe(probe_row); |
| 611 | EXPECT_TRUE(passes); |
| 612 | iter = hash_table->FindProbeRow(ht_ctx.get()); |
| 613 | EXPECT_TRUE(iter.AtEnd()); |
nothing calls this directly
no test coverage detected