OmniSciDB  04ee39c94c
GroupByHashTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "RuntimeFunctions.h"
18 
19 #include <gtest/gtest.h>
20 #include <cstdint>
21 #include <numeric>
22 
23 namespace {
24 
25 void init_groups(int64_t* groups_buffer,
26  const int32_t groups_buffer_entry_count,
27  const int32_t key_qw_count,
28  const int64_t* init_vals) {
29  int32_t groups_buffer_entry_qw_count = groups_buffer_entry_count * (key_qw_count + 1);
30  for (int32_t i = 0; i < groups_buffer_entry_qw_count; ++i) {
31  groups_buffer[i] = (i % (key_qw_count + 1) < key_qw_count)
32  ? EMPTY_KEY_64
33  : init_vals[(i - key_qw_count) % (key_qw_count + 1)];
34  }
35 }
36 
37 } // namespace
38 
39 class GroupsBuffer {
40  public:
42  const size_t key_qw_count,
43  const int64_t init_val)
44  : size_{groups_buffer_entry_count * (key_qw_count + 1)} {
45  groups_buffer_ = new int64_t[size_];
46  init_groups(groups_buffer_, groups_buffer_entry_count, key_qw_count, &init_val);
47  }
48  ~GroupsBuffer() { delete[] groups_buffer_; }
49  operator int64_t*() const { return groups_buffer_; }
50  size_t qw_size() const { return size_; }
51 
52  private:
53  int64_t* groups_buffer_;
54  const size_t size_;
55 };
56 
57 TEST(InitTest, OneKey) {
58  const int32_t groups_buffer_entry_count{10};
59  const int32_t key_qw_count{1};
61  auto gb_raw = static_cast<int64_t*>(gb);
62  for (size_t i = 0; i < gb.qw_size(); i += 2) {
63  ASSERT_EQ(gb_raw[i], EMPTY_KEY_64);
64  }
65 }
66 
67 TEST(SetGetTest, OneKey) {
68  const int32_t groups_buffer_entry_count{10};
69  const int32_t key_qw_count{1};
70  const int32_t row_size_quad{key_qw_count + 1};
72  int64_t key = 31;
73  auto gv1 = get_group_value(
74  gb, groups_buffer_entry_count, &key, key_qw_count, sizeof(int64_t), row_size_quad);
75  ASSERT_NE(gv1, nullptr);
76  auto gv2 = get_group_value(
77  gb, groups_buffer_entry_count, &key, key_qw_count, sizeof(int64_t), row_size_quad);
78  ASSERT_EQ(gv1, gv2);
79  int64_t val = 42;
80  *gv2 = val;
81  auto gv3 = get_group_value(
82  gb, groups_buffer_entry_count, &key, key_qw_count, sizeof(int64_t), row_size_quad);
83  ASSERT_NE(gv3, nullptr);
84  ASSERT_EQ(*gv3, val);
85 }
86 
87 TEST(SetGetTest, ManyKeys) {
88  const int32_t groups_buffer_entry_count{10};
89  const int32_t key_qw_count{5};
90  const int32_t row_size_quad{key_qw_count + 1};
92  int64_t key[] = {31, 32, 33, 34, 35};
93  auto gv1 = get_group_value(
94  gb, groups_buffer_entry_count, key, key_qw_count, sizeof(int64_t), row_size_quad);
95  ASSERT_NE(gv1, nullptr);
96  auto gv2 = get_group_value(
97  gb, groups_buffer_entry_count, key, key_qw_count, sizeof(int64_t), row_size_quad);
98  ASSERT_EQ(gv1, gv2);
99  int64_t val = 42;
100  *gv2 = val;
101  auto gv3 = get_group_value(
102  gb, groups_buffer_entry_count, key, key_qw_count, sizeof(int64_t), row_size_quad);
103  ASSERT_NE(gv3, nullptr);
104  ASSERT_EQ(*gv3, val);
105 }
106 
107 TEST(SetGetTest, OneKeyCollision) {
108  const int32_t groups_buffer_entry_count{10};
109  const int32_t key_qw_count{1};
110  const int32_t row_size_quad{key_qw_count + 1};
112  int64_t key1 = 31;
113  auto gv1 = get_group_value(
114  gb, groups_buffer_entry_count, &key1, key_qw_count, sizeof(int64_t), row_size_quad);
115  ASSERT_NE(gv1, nullptr);
116  int64_t val1 = 32;
117  *gv1 = val1;
118  int64_t key2 = 41;
119  auto gv2 = get_group_value(
120  gb, groups_buffer_entry_count, &key2, key_qw_count, sizeof(int64_t), row_size_quad);
121  ASSERT_NE(gv2, nullptr);
122  int64_t val2 = 42;
123  *gv2 = val2;
124  gv1 = get_group_value(
125  gb, groups_buffer_entry_count, &key1, key_qw_count, sizeof(int64_t), row_size_quad);
126  ASSERT_NE(gv1, nullptr);
127  ASSERT_EQ(*gv1, val1);
128  gv2 = get_group_value(
129  gb, groups_buffer_entry_count, &key2, key_qw_count, sizeof(int64_t), row_size_quad);
130  ASSERT_NE(gv2, nullptr);
131  ASSERT_EQ(*gv2, val2);
132 }
133 
134 TEST(SetGetTest, OneKeyRandom) {
135  const int32_t groups_buffer_entry_count{10};
136  const int32_t key_qw_count{1};
137  const int32_t row_size_quad{key_qw_count + 1};
139  std::vector<int64_t> keys;
140  for (int32_t i = 0; i < groups_buffer_entry_count; ++i) {
141  int64_t key = rand() % 1000;
142  keys.push_back(key);
143  auto gv = get_group_value(gb,
144  groups_buffer_entry_count,
145  &key,
146  key_qw_count,
147  sizeof(int64_t),
148  row_size_quad);
149  ASSERT_NE(gv, nullptr);
150  *gv = key + 100;
151  }
152  for (const auto key : keys) {
153  auto gv = get_group_value(gb,
154  groups_buffer_entry_count,
155  &key,
156  key_qw_count,
157  sizeof(int64_t),
158  row_size_quad);
159  ASSERT_NE(gv, nullptr);
160  ASSERT_EQ(*gv, key + 100);
161  }
162 }
163 
164 TEST(SetGetTest, MultiKeyRandom) {
165  const int32_t groups_buffer_entry_count{10};
166  const int32_t key_qw_count{5};
167  const int32_t row_size_quad{key_qw_count + 1};
169  std::vector<std::vector<int64_t>> keys;
170  for (int32_t i = 0; i < groups_buffer_entry_count; ++i) {
171  std::vector<int64_t> key;
172  for (int32_t i = 0; i < key_qw_count; ++i) {
173  key.push_back(rand() % 1000);
174  }
175  keys.push_back(key);
176  auto gv = get_group_value(gb,
177  groups_buffer_entry_count,
178  &key[0],
179  key_qw_count,
180  sizeof(int64_t),
181  row_size_quad);
182  ASSERT_NE(gv, nullptr);
183  *gv = std::accumulate(
184  key.begin(), key.end(), 100, [](int64_t x, int64_t y) { return x + y; });
185  }
186  for (const auto key : keys) {
187  auto gv = get_group_value(gb,
188  groups_buffer_entry_count,
189  &key[0],
190  key_qw_count,
191  sizeof(int64_t),
192  row_size_quad);
193  ASSERT_NE(gv, nullptr);
194  ASSERT_EQ(*gv, std::accumulate(key.begin(), key.end(), 100, [](int64_t x, int64_t y) {
195  return x + y;
196  }));
197  }
198 }
199 
200 TEST(SetGetTest, OneKeyNoCollisions) {
201  const int32_t groups_buffer_entry_count{10};
202  const int32_t key_qw_count{1};
203  const int32_t row_size_quad{key_qw_count + 1};
205  int64_t key_start = 31;
206  for (int32_t i = 0; i < groups_buffer_entry_count; ++i) {
207  int64_t key = key_start + i;
208  auto gv = get_group_value(gb,
209  groups_buffer_entry_count,
210  &key,
211  key_qw_count,
212  sizeof(int64_t),
213  row_size_quad);
214  ASSERT_NE(gv, nullptr);
215  *gv = key + 100;
216  }
217  for (int32_t i = 0; i < groups_buffer_entry_count; ++i) {
218  int64_t key = key_start + i;
219  auto gv = get_group_value(gb,
220  groups_buffer_entry_count,
221  &key,
222  key_qw_count,
223  sizeof(int64_t),
224  row_size_quad);
225  ASSERT_NE(gv, nullptr);
226  ASSERT_EQ(*gv, key + 100);
227  }
228  int64_t key = key_start + groups_buffer_entry_count;
229  auto gv = get_group_value(
230  gb, groups_buffer_entry_count, &key, key_qw_count, sizeof(int64_t), row_size_quad);
231  ASSERT_EQ(gv, nullptr);
232 }
233 
234 TEST(SetGetTest, OneKeyAllCollisions) {
235  const int32_t groups_buffer_entry_count{10};
236  const int32_t key_qw_count{1};
237  const int32_t row_size_quad{key_qw_count + 1};
239  int64_t key_start = 31;
240  for (int32_t i = 0; i < groups_buffer_entry_count; ++i) {
241  int64_t key = key_start + groups_buffer_entry_count * i;
242  auto gv = get_group_value(gb,
243  groups_buffer_entry_count,
244  &key,
245  key_qw_count,
246  sizeof(int64_t),
247  row_size_quad);
248  ASSERT_NE(gv, nullptr);
249  *gv = key + 100;
250  }
251  for (int32_t i = 0; i < groups_buffer_entry_count; ++i) {
252  int64_t key = key_start + groups_buffer_entry_count * i;
253  auto gv = get_group_value(gb,
254  groups_buffer_entry_count,
255  &key,
256  key_qw_count,
257  sizeof(int64_t),
258  row_size_quad);
259  ASSERT_NE(gv, nullptr);
260  ASSERT_EQ(*gv, key + 100);
261  }
262  int64_t key = key_start + groups_buffer_entry_count * groups_buffer_entry_count;
263  auto gv = get_group_value(
264  gb, groups_buffer_entry_count, &key, key_qw_count, sizeof(int64_t), row_size_quad);
265  ASSERT_EQ(gv, nullptr);
266 }
267 
268 int main(int argc, char** argv) {
269  testing::InitGoogleTest(&argc, argv);
270  return RUN_ALL_TESTS();
271 }
int main(int argc, char **argv)
#define EMPTY_KEY_64
const int64_t const uint32_t groups_buffer_entry_count
const int64_t const uint32_t const uint32_t key_qw_count
TEST(InitTest, OneKey)
void init_groups(int64_t *groups_buffer, const int32_t groups_buffer_entry_count, const int32_t key_qw_count, const int64_t *init_vals)
NEVER_INLINE DEVICE int64_t * get_group_value(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_count, const uint32_t key_width, const uint32_t row_size_quad, const int64_t *init_vals)
const size_t size_
int64_t * groups_buffer_
GroupsBuffer(const size_t groups_buffer_entry_count, const size_t key_qw_count, const int64_t init_val)
size_t qw_size() const
const int64_t * init_vals