OmniSciDB  c1a53651b2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HashJoinKeyHandlers.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, 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 #ifndef QUERYENGINE_HASHJOINKEYHANDLERS_H
18 #define QUERYENGINE_HASHJOINKEYHANDLERS_H
19 
22 #include "Shared/SqlTypesLayout.h"
23 
24 #ifdef __CUDACC__
26 #else
27 #include "Logger/Logger.h"
31 #endif
32 
34 
35 #include <cmath>
36 
37 #include "Shared/funcannotations.h"
38 
40  GenericKeyHandler(const size_t key_component_count,
41  const bool should_skip_entries,
42  const JoinColumn* join_column_per_key,
43  const JoinColumnTypeInfo* type_info_per_key
44 #ifndef __CUDACC__
45  ,
46  const int32_t* const* sd_inner_to_outer_translation_maps,
47  const int32_t* sd_min_inner_elems
48 #endif
49  )
50  : key_component_count_(key_component_count)
51  , should_skip_entries_(should_skip_entries)
52  , join_column_per_key_(join_column_per_key)
53  , type_info_per_key_(type_info_per_key) {
54 #ifndef __CUDACC__
55  if (sd_inner_to_outer_translation_maps) {
56  CHECK(sd_min_inner_elems);
57  sd_inner_to_outer_translation_maps_ = sd_inner_to_outer_translation_maps;
58  sd_min_inner_elems_ = sd_min_inner_elems;
59  } else
60 #endif
61  {
63  sd_min_inner_elems_ = nullptr;
64  }
65  }
66 
67  template <typename T, typename KEY_BUFF_HANDLER>
68  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
69  T* key_scratch_buff,
70  KEY_BUFF_HANDLER f) const {
71  bool skip_entry = false;
72  for (size_t key_component_index = 0; key_component_index < key_component_count_;
73  ++key_component_index) {
74  const auto& join_column_iterator = join_column_iterators[key_component_index];
75  int64_t elem = (*join_column_iterator).element;
76  if (should_skip_entries_ && elem == join_column_iterator.type_info->null_val &&
77  !join_column_iterator.type_info->uses_bw_eq) {
78  skip_entry = true;
79  break;
80  }
81 #ifndef __CUDACC__
82  // Translation map pts will already be set to nullptr if invalid
84  const auto sd_inner_to_outer_translation_map =
85  sd_inner_to_outer_translation_maps_[key_component_index];
86  const auto sd_min_inner_elem = sd_min_inner_elems_[key_component_index];
87  if (sd_inner_to_outer_translation_map &&
88  elem != join_column_iterator.type_info->null_val) {
89  const auto outer_id =
90  sd_inner_to_outer_translation_map[elem - sd_min_inner_elem];
91  if (outer_id == StringDictionary::INVALID_STR_ID) {
92  skip_entry = true;
93  break;
94  }
95  elem = outer_id;
96  }
97  }
98 #endif
99  key_scratch_buff[key_component_index] = elem;
100  }
101 
102  if (!skip_entry) {
103  return f(join_column_iterators[0].index, key_scratch_buff, key_component_count_);
104  }
105 
106  return 0;
107  }
108 
110 
112 
114 
116  return type_info_per_key_;
117  }
118 
119  const size_t key_component_count_;
123  const int32_t* const* sd_inner_to_outer_translation_maps_;
124  const int32_t* sd_min_inner_elems_;
125 };
126 
128  OverlapsKeyHandler(const size_t key_dims_count,
129  const JoinColumn* join_column, // always 1 column
130  const double* bucket_sizes_for_dimension)
131  : key_dims_count_(key_dims_count)
132  , join_column_(join_column)
133  , bucket_sizes_for_dimension_(bucket_sizes_for_dimension) {}
134 
135  template <typename T, typename KEY_BUFF_HANDLER>
136  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
137  T* key_scratch_buff,
138  KEY_BUFF_HANDLER f) const {
139  // TODO(adb): hard-coding the 2D case w/ bounds for now. Should support n-dims with a
140  // check to ensure we are not exceeding maximum number of dims for coalesced keys
141  double bounds[4];
142  for (size_t j = 0; j < 2 * key_dims_count_; j++) {
143  bounds[j] =
144  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), j);
145  }
146 
147  const auto x_bucket_sz = bucket_sizes_for_dimension_[0];
148  const auto y_bucket_sz = bucket_sizes_for_dimension_[1];
149 
150  for (int64_t x = floor(bounds[0] * x_bucket_sz); x <= floor(bounds[2] * x_bucket_sz);
151  x++) {
152  for (int64_t y = floor(bounds[1] * y_bucket_sz);
153  y <= floor(bounds[3] * y_bucket_sz);
154  y++) {
155  key_scratch_buff[0] = x;
156  key_scratch_buff[1] = y;
157 
158  const auto err =
159  f(join_column_iterators[0].index, key_scratch_buff, key_dims_count_);
160  if (err) {
161  return err;
162  }
163  }
164  }
165  return 0;
166  }
167 
168  DEVICE size_t get_number_of_columns() const { return 1; }
169 
170  DEVICE size_t get_key_component_count() const { return key_dims_count_; }
171 
172  DEVICE const JoinColumn* get_join_columns() const { return join_column_; }
173 
174  DEVICE const JoinColumnTypeInfo* get_join_column_type_infos() const { return nullptr; }
175 
176  const size_t key_dims_count_;
179 };
180 
182  explicit RangeKeyHandler(const bool is_compressed,
183  const size_t key_dims_count,
184  const JoinColumn* join_column, // always 1 column
185  const double* bucket_sizes_for_dimension)
186  : is_compressed_(is_compressed)
187  , key_dims_count_(key_dims_count)
188  , join_column_(join_column)
189  , bucket_sizes_for_dimension_(bucket_sizes_for_dimension) {}
190 
191  template <typename T, typename KEY_BUFF_HANDLER>
192  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
193  T* key_scratch_buff,
194  KEY_BUFF_HANDLER f) const {
195  double coords[2];
196 
197  if (is_compressed_) {
200  join_column_iterators->ptr(), /*byte_width=*/4, 0));
203  join_column_iterators->ptr(), /*byte_width=*/4, 1));
204  } else {
205  coords[0] =
206  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), 0);
207  coords[1] =
208  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), 1);
209  }
210 
211  const auto x_bucket_sz = bucket_sizes_for_dimension_[0];
212  const auto y_bucket_sz = bucket_sizes_for_dimension_[1];
213 
214  key_scratch_buff[0] = floor(coords[0] * x_bucket_sz);
215  key_scratch_buff[1] = floor(coords[1] * y_bucket_sz);
216  const auto err = f(join_column_iterators[0].index, key_scratch_buff, key_dims_count_);
217  if (err) {
218  return err;
219  }
220 
221  return 0;
222  }
223 
224  DEVICE size_t get_number_of_columns() const { return 1; }
225 
226  DEVICE size_t get_key_component_count() const { return key_dims_count_; }
227 
228  DEVICE const JoinColumn* get_join_columns() const { return join_column_; }
229 
230  DEVICE const JoinColumnTypeInfo* get_join_column_type_infos() const { return nullptr; }
231 
232  const bool is_compressed_;
233  const size_t key_dims_count_;
236 };
237 
238 #endif // QUERYENGINE_HASHJOINKEYHANDLERS_H
DEVICE size_t get_key_component_count() const
const JoinColumn * join_column_per_key_
const size_t key_dims_count_
OverlapsKeyHandler(const size_t key_dims_count, const JoinColumn *join_column, const double *bucket_sizes_for_dimension)
DEVICE size_t get_number_of_columns() const
DEVICE double decompress_latitude_coord_geoint32(const int32_t compressed)
const size_t key_component_count_
DEVICE NEVER_INLINE int64_t SUFFIX() fixed_width_int_decode_noinline(const int8_t *byte_stream, const int32_t byte_width, const int64_t pos)
Definition: DecodersImpl.h:91
DEVICE int operator()(JoinColumnIterator *join_column_iterators, T *key_scratch_buff, KEY_BUFF_HANDLER f) const
DEVICE const JoinColumn * get_join_columns() const
#define SUFFIX(name)
const double * bucket_sizes_for_dimension_
DEVICE const JoinColumnTypeInfo * get_join_column_type_infos() const
DEVICE const JoinColumnTypeInfo * get_join_column_type_infos() const
const double * bucket_sizes_for_dimension_
RangeKeyHandler(const bool is_compressed, const size_t key_dims_count, const JoinColumn *join_column, const double *bucket_sizes_for_dimension)
constexpr double f
Definition: Utm.h:31
GenericKeyHandler(const size_t key_component_count, const bool should_skip_entries, const JoinColumn *join_column_per_key, const JoinColumnTypeInfo *type_info_per_key, const int32_t *const *sd_inner_to_outer_translation_maps, const int32_t *sd_min_inner_elems)
#define DEVICE
static constexpr int32_t INVALID_STR_ID
Iterates over the rows of a JoinColumn across multiple fragments/chunks.
DEVICE size_t get_key_component_count() const
DEVICE size_t get_key_component_count() const
DEVICE const JoinColumn * get_join_columns() const
DEVICE double decompress_longitude_coord_geoint32(const int32_t compressed)
DEVICE int operator()(JoinColumnIterator *join_column_iterators, T *key_scratch_buff, KEY_BUFF_HANDLER f) const
const JoinColumnTypeInfo * type_info_per_key_
DEVICE const JoinColumn * get_join_columns() const
const int32_t *const * sd_inner_to_outer_translation_maps_
DEVICE size_t get_number_of_columns() const
#define CHECK(condition)
Definition: Logger.h:291
DEVICE int operator()(JoinColumnIterator *join_column_iterators, T *key_scratch_buff, KEY_BUFF_HANDLER f) const
DEVICE NEVER_INLINE double SUFFIX() fixed_width_double_decode_noinline(const int8_t *byte_stream, const int64_t pos)
Definition: DecodersImpl.h:134
const JoinColumn * join_column_
const int32_t * sd_min_inner_elems_
DEVICE FORCE_INLINE const int8_t * ptr() const
const size_t key_dims_count_
DEVICE const JoinColumnTypeInfo * get_join_column_type_infos() const
DEVICE size_t get_number_of_columns() const
const JoinColumn * join_column_
const bool should_skip_entries_