20 #include <gtest/gtest.h> 
   59     EXPECT_TRUE(status.
ok());
 
   61     EXPECT_TRUE(status.ok());
 
   66     EXPECT_TRUE(status.ok());
 
   68     EXPECT_TRUE(status.ok());
 
   79     *
reinterpret_cast<int32_t*
>(tuple_mem) = val;
 
   98     while (!iter.
AtEnd()) {
 
  100       int32_t val = *
reinterpret_cast<int32_t*
>(
build_expr_ctxs_[0]->GetValue(row));
 
  103       if (all_unique) EXPECT_TRUE(results[val] == NULL);
 
  113     EXPECT_TRUE(probe_row != build_row);
 
  118     EXPECT_EQ(build_val, probe_val);
 
  129     for (
int i = 0; i < num_data; ++i) {
 
  134       iter = table->
Find(ht_ctx, hash);
 
  136       if (data[i].expected_build_rows.size() == 0) {
 
  137         EXPECT_TRUE(iter.
AtEnd());
 
  140           map<TupleRow*, bool> matched;
 
  141           while (!iter.
AtEnd()) {
 
  142             EXPECT_EQ(matched.find(iter.
GetRow()), matched.end());
 
  143             matched[iter.
GetRow()] = 
true;
 
  148             EXPECT_TRUE(matched[data[i].expected_build_rows[j]]);
 
  151           EXPECT_EQ(data[i].expected_build_rows.size(), 1);
 
  152           EXPECT_EQ(data[i].expected_build_rows[0]->GetTuple(0),
 
  169     EXPECT_EQ(*val_row1, 1);
 
  172     EXPECT_EQ(*val_row2, 2);
 
  175     EXPECT_EQ(*val_row3, 3);
 
  178     EXPECT_EQ(*val_row4, 4);
 
  196     for (
int i = 0; i < 10; ++i) {
 
  207     EXPECT_TRUE(success);
 
  208     for (
int i = 0; i < 5; ++i) {
 
  210       bool inserted = hash_table.
Insert(&ht_ctx, build_rows[i]->GetTuple(0), hash);
 
  211       EXPECT_TRUE(inserted);
 
  213     EXPECT_EQ(hash_table.
size(), 5);
 
  216     FullScan(&hash_table, &ht_ctx, 0, 5, 
true, scan_rows, build_rows);
 
  217     ProbeTest(&hash_table, &ht_ctx, probe_rows, 10, 
false);
 
  222     EXPECT_EQ(hash_table.
size(), 5);
 
  223     memset(scan_rows, 0, 
sizeof(scan_rows));
 
  224     FullScan(&hash_table, &ht_ctx, 0, 5, 
true, scan_rows, build_rows);
 
  225     ProbeTest(&hash_table, &ht_ctx, probe_rows, 10, 
false);
 
  230     EXPECT_EQ(hash_table.
size(), 5);
 
  231     memset(scan_rows, 0, 
sizeof(scan_rows));
 
  232     FullScan(&hash_table, &ht_ctx, 0, 5, 
true, scan_rows, build_rows);
 
  233     ProbeTest(&hash_table, &ht_ctx, probe_rows, 10, 
false);
 
  238     EXPECT_EQ(hash_table.
size(), 5);
 
  239     memset(scan_rows, 0, 
sizeof(scan_rows));
 
  240     FullScan(&hash_table, &ht_ctx, 0, 5, 
true, scan_rows, build_rows);
 
  241     ProbeTest(&hash_table, &ht_ctx, probe_rows, 10, 
false);
 
  247   void ScanTest(
bool quadratic, 
int initial_size, 
int rows_to_insert,
 
  248                 int additional_rows) {
 
  249     int total_rows = rows_to_insert + additional_rows;
 
  255     vector<TupleRow*> build_rows;
 
  259     for (
int val = 1; val <= rows_to_insert; ++val) {
 
  261       EXPECT_TRUE(success) << 
" failed to resize: " << val;
 
  263       for (
int i = 0; i < val; ++i) {
 
  267         build_rows.push_back(row);
 
  273     for (
int val = rows_to_insert; val < rows_to_insert + additional_rows; ++val) {
 
  278     ProbeTest(&hash_table, &ht_ctx, probe_rows, total_rows, 
true);
 
  284     ProbeTest(&hash_table, &ht_ctx, probe_rows, total_rows, 
true);
 
  289     ProbeTest(&hash_table, &ht_ctx, probe_rows, total_rows, 
true);
 
  291     delete [] probe_rows;
 
  300     int expected_size = 0;
 
  305     HashTable hash_table(&pool, quadratic, num_to_add);
 
  310     int build_row_val = 0;
 
  312     for (
int i = 0; i < 20; ++i) {
 
  318       EXPECT_TRUE(success) << 
" failed to resize: " << num_to_add;
 
  319       for (
int j = 0; j < num_to_add; ++build_row_val, ++j) {
 
  323         if (!inserted) 
goto done_inserting;
 
  325       expected_size += num_to_add;
 
  330     EXPECT_EQ(hash_table.
size(), 4194300);
 
  332     for (
int i = 0; i < expected_size * 5; i += 100000) {
 
  336       if (i < hash_table.
size()) {
 
  337         EXPECT_TRUE(!iter.
AtEnd()) << 
" i: " << i;
 
  340         EXPECT_TRUE(iter.
AtEnd()) << 
" i: " << i;
 
  356     HashTable hash_table(&pool, quadratic, table_size);
 
  364     for (
int build_row_val = 0; build_row_val < table_size; ++build_row_val) {
 
  369       EXPECT_TRUE(inserted);
 
  370       EXPECT_EQ(hash_table.
EmptyBuckets(), table_size - build_row_val - 1);
 
  374       iter = hash_table.
Find(&ht_ctx, hash);
 
  375       EXPECT_FALSE(iter.
AtEnd());
 
  384     iter = hash_table.
Find(&ht_ctx, hash);
 
  385     EXPECT_TRUE(iter.
AtEnd());
 
  394   SetupTest(
false, 1024);
 
  395   SetupTest(
false, 65536);
 
  400   SetupTest(
true, 1024);
 
  401   SetupTest(
true, 65536);
 
  406   BasicTest(
false, 1024);
 
  407   BasicTest(
false, 65536);
 
  412   BasicTest(
true, 1024);
 
  413   BasicTest(
true, 65536);
 
  418   ScanTest(
false, 1, 10, 5);
 
  419   ScanTest(
false, 1024, 1000, 5);
 
  420   ScanTest(
false, 1024, 1000, 500);
 
  424   ScanTest(
true, 1, 10, 5);
 
  425   ScanTest(
true, 1024, 1000, 5);
 
  426   ScanTest(
true, 1024, 1000, 500);
 
  430   GrowTableTest(
false);
 
  438   InsertFullTest(
false, 1);
 
  439   InsertFullTest(
false, 4);
 
  440   InsertFullTest(
false, 64);
 
  441   InsertFullTest(
false, 1024);
 
  442   InsertFullTest(
false, 65536);
 
  446   InsertFullTest(
true, 1);
 
  447   InsertFullTest(
true, 4);
 
  448   InsertFullTest(
true, 64);
 
  449   InsertFullTest(
true, 1024);
 
  450   InsertFullTest(
true, 65536);
 
  455 int main(
int argc, 
char** argv) {
 
  456   ::testing::InitGoogleTest(&argc, argv);
 
  458   return RUN_ALL_TESTS();
 
vector< ExprContext * > build_expr_ctxs_
 
stl-like iterator interface. 
 
void SetupTest(bool quadratic, int table_size)
 
bool AtEnd() const 
Returns true if this iterator is at the end, i.e. GetRow() cannot be called. 
 
void ValidateMatch(TupleRow *probe_row, TupleRow *build_row)
 
TEST_F(InstructionCounterTest, Count)
 
Tuple * GetTuple(int tuple_idx)
 
void BasicTest(bool quadratic, int table_size)
 
void InsertFullTest(bool quadratic, int table_size)
 
void FullScan(HashTable *table, HashTableCtx *ht_ctx, int min, int max, bool all_unique, TupleRow **results, TupleRow **expected)
 
static Status Open(const std::vector< ExprContext * > &ctxs, RuntimeState *state)
Convenience function for opening multiple expr trees. 
 
void ScanTest(bool quadratic, int initial_size, int rows_to_insert, int additional_rows)
 
A tuple with 0 materialised slots is represented as NULL. 
 
const StringSearch UrlParser::hash_search & hash
 
vector< TupleRow * > expected_build_rows
 
Iterator Begin(HashTableCtx *ht_ctx)
 
bool CheckAndResize(uint64_t buckets_to_fill, HashTableCtx *ht_ctx)
 
int64_t EmptyBuckets() const 
Returns the number of empty buckets. 
 
static Tuple * Create(int size, MemPool *pool)
initialize individual tuple with data residing in mem pool 
 
void ProbeTest(HashTable *table, HashTableCtx *ht_ctx, ProbeTestData *data, int num_data, bool scan)
 
static void Close(const std::vector< ExprContext * > &ctxs, RuntimeState *state)
Convenience function for closing multiple expr trees. 
 
void GrowTableTest(bool quadratic)
 
vector< ExprContext * > probe_expr_ctxs_
 
void IR_ALWAYS_INLINE Next()
Iterates to the next element. It should be called only if !AtEnd(). 
 
This is the superclass of all expr evaluation nodes. 
 
bool ResizeBuckets(int64_t num_buckets, HashTableCtx *ht_ctx)
Resize the hash table to 'num_buckets'. Returns false on OOM. 
 
This class is thread-safe. 
 
uint64_t Test(T *ht, const ProbeTuple *input, uint64_t num_tuples)
 
void SetTuple(int tuple_idx, Tuple *tuple)
 
static int64_t NextPowerOfTwo(int64_t v)
 
int64_t num_buckets() const 
Returns the number of buckets. 
 
int main(int argc, char **argv)
 
TupleRow * CreateTupleRow(int32_t val)
 
Reference to a single slot of a tuple. 
 
Iterator IR_ALWAYS_INLINE Find(HashTableCtx *ht_ctx, uint32_t hash)
 
static void Init()
Initialize CpuInfo. 
 
static Status Prepare(const std::vector< ExprContext * > &ctxs, RuntimeState *state, const RowDescriptor &row_desc, MemTracker *tracker)
 
void ResizeTable(HashTable *table, int64_t new_size, HashTableCtx *ht_ctx)
 
void Close()
Call to cleanup any resources. Must be called once. 
 
bool IR_ALWAYS_INLINE EvalAndHashBuild(TupleRow *row, uint32_t *hash)
 
TupleRow * GetRow() const 
 
bool IR_ALWAYS_INLINE Insert(HashTableCtx *ht_ctx, const BufferedTupleStream::RowIdx &idx, TupleRow *row, uint32_t hash)
 
int64_t size() const 
Returns number of elements inserted in the hash table. 
 
uint8_t * Allocate(int size)
 
bool IR_ALWAYS_INLINE EvalAndHashProbe(TupleRow *row, uint32_t *hash)