OmniSciDB  6686921089
 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 2018 OmniSci, 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 void* const* sd_inner_proxy_per_key,
47  const void* const* sd_outer_proxy_per_key
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_proxy_per_key) {
56  CHECK(sd_outer_proxy_per_key);
57  sd_inner_proxy_per_key_ = sd_inner_proxy_per_key;
58  sd_outer_proxy_per_key_ = sd_outer_proxy_per_key;
59  } else
60 #endif
61  {
62  sd_inner_proxy_per_key_ = nullptr;
63  sd_outer_proxy_per_key_ = 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  const auto sd_inner_proxy = sd_inner_proxy_per_key_
83  ? sd_inner_proxy_per_key_[key_component_index]
84  : nullptr;
85  const auto sd_outer_proxy = sd_outer_proxy_per_key_
86  ? sd_outer_proxy_per_key_[key_component_index]
87  : nullptr;
88  if (sd_inner_proxy && elem != join_column_iterator.type_info->null_val) {
89  CHECK(sd_outer_proxy);
90  const auto sd_inner_dict_proxy =
91  static_cast<const StringDictionaryProxy*>(sd_inner_proxy);
92  const auto sd_outer_dict_proxy =
93  static_cast<const StringDictionaryProxy*>(sd_outer_proxy);
94  const auto elem_str = sd_inner_dict_proxy->getString(elem);
95  const auto outer_id = sd_outer_dict_proxy->getIdOfString(elem_str);
96  if (outer_id == StringDictionary::INVALID_STR_ID) {
97  skip_entry = true;
98  break;
99  }
100  elem = outer_id;
101  }
102 #endif
103  key_scratch_buff[key_component_index] = elem;
104  }
105 
106  if (!skip_entry) {
107  return f(join_column_iterators[0].index, key_scratch_buff, key_component_count_);
108  }
109 
110  return 0;
111  }
112 
114 
116 
118 
120  return type_info_per_key_;
121  }
122 
123  const size_t key_component_count_;
127  const void* const* sd_inner_proxy_per_key_;
128  const void* const* sd_outer_proxy_per_key_;
129 };
130 
132  OverlapsKeyHandler(const size_t key_dims_count,
133  const JoinColumn* join_column, // always 1 column
134  const double* bucket_sizes_for_dimension)
135  : key_dims_count_(key_dims_count)
136  , join_column_(join_column)
137  , bucket_sizes_for_dimension_(bucket_sizes_for_dimension) {}
138 
139  template <typename T, typename KEY_BUFF_HANDLER>
140  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
141  T* key_scratch_buff,
142  KEY_BUFF_HANDLER f) const {
143  // TODO(adb): hard-coding the 2D case w/ bounds for now. Should support n-dims with a
144  // check to ensure we are not exceeding maximum number of dims for coalesced keys
145  double bounds[4];
146  for (size_t j = 0; j < 2 * key_dims_count_; j++) {
147  bounds[j] =
148  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), j);
149  }
150 
151  const auto x_bucket_sz = bucket_sizes_for_dimension_[0];
152  const auto y_bucket_sz = bucket_sizes_for_dimension_[1];
153 
154  for (int64_t x = floor(bounds[0] * x_bucket_sz); x <= floor(bounds[2] * x_bucket_sz);
155  x++) {
156  for (int64_t y = floor(bounds[1] * y_bucket_sz);
157  y <= floor(bounds[3] * y_bucket_sz);
158  y++) {
159  key_scratch_buff[0] = x;
160  key_scratch_buff[1] = y;
161 
162  const auto err =
163  f(join_column_iterators[0].index, key_scratch_buff, key_dims_count_);
164  if (err) {
165  return err;
166  }
167  }
168  }
169  return 0;
170  }
171 
172  DEVICE size_t get_number_of_columns() const { return 1; }
173 
174  DEVICE size_t get_key_component_count() const { return key_dims_count_; }
175 
176  DEVICE const JoinColumn* get_join_columns() const { return join_column_; }
177 
178  DEVICE const JoinColumnTypeInfo* get_join_column_type_infos() const { return nullptr; }
179 
180  const size_t key_dims_count_;
183 };
184 
186  explicit RangeKeyHandler(const bool is_compressed,
187  const size_t key_dims_count,
188  const JoinColumn* join_column, // always 1 column
189  const double* bucket_sizes_for_dimension)
190  : is_compressed_(is_compressed)
191  , key_dims_count_(key_dims_count)
192  , join_column_(join_column)
193  , bucket_sizes_for_dimension_(bucket_sizes_for_dimension) {}
194 
195  template <typename T, typename KEY_BUFF_HANDLER>
196  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
197  T* key_scratch_buff,
198  KEY_BUFF_HANDLER f) const {
199  double coords[2];
200 
201  if (is_compressed_) {
204  join_column_iterators->ptr(), /*byte_width=*/4, 0));
207  join_column_iterators->ptr(), /*byte_width=*/4, 1));
208  } else {
209  coords[0] =
210  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), 0);
211  coords[1] =
212  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), 1);
213  }
214 
215  const auto x_bucket_sz = bucket_sizes_for_dimension_[0];
216  const auto y_bucket_sz = bucket_sizes_for_dimension_[1];
217 
218  key_scratch_buff[0] = floor(coords[0] * x_bucket_sz);
219  key_scratch_buff[1] = floor(coords[1] * y_bucket_sz);
220  const auto err = f(join_column_iterators[0].index, key_scratch_buff, key_dims_count_);
221  if (err) {
222  return err;
223  }
224 
225  return 0;
226  }
227 
228  DEVICE size_t get_number_of_columns() const { return 1; }
229 
230  DEVICE size_t get_key_component_count() const { return key_dims_count_; }
231 
232  DEVICE const JoinColumn* get_join_columns() const { return join_column_; }
233 
234  DEVICE const JoinColumnTypeInfo* get_join_column_type_infos() const { return nullptr; }
235 
236  const bool is_compressed_;
237  const size_t key_dims_count_;
240 };
241 
242 #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
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 double decompress_lattitude_coord_geoint32(const int32_t compressed)
const void *const * sd_inner_proxy_per_key_
DEVICE const JoinColumn * get_join_columns() const
#define SUFFIX(name)
const double * bucket_sizes_for_dimension_
std::string getString(int32_t string_id) const
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)
const void *const * sd_outer_proxy_per_key_
#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
DEVICE size_t get_number_of_columns() const
#define CHECK(condition)
Definition: Logger.h:209
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
char * f
const JoinColumn * join_column_
DEVICE FORCE_INLINE const int8_t * ptr() const
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 void *const *sd_inner_proxy_per_key, const void *const *sd_outer_proxy_per_key)
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_