OmniSciDB  340b00dbf6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 
20 #include "../../Shared/SqlTypesLayout.h"
21 #include "HashJoinRuntime.h"
22 #include "JoinColumnIterator.h"
23 
24 #ifdef __CUDACC__
25 #include "../DecodersImpl.h"
26 #else
27 #include "Logger/Logger.h"
31 #endif
32 
33 #include <cmath>
34 
35 #include "../../Shared/funcannotations.h"
36 
38  GenericKeyHandler(const size_t key_component_count,
39  const bool should_skip_entries,
40  const JoinColumn* join_column_per_key,
41  const JoinColumnTypeInfo* type_info_per_key
42 #ifndef __CUDACC__
43  ,
44  const void* const* sd_inner_proxy_per_key,
45  const void* const* sd_outer_proxy_per_key
46 #endif
47  )
48  : key_component_count_(key_component_count)
49  , should_skip_entries_(should_skip_entries)
50  , join_column_per_key_(join_column_per_key)
51  , type_info_per_key_(type_info_per_key) {
52 #ifndef __CUDACC__
53  if (sd_inner_proxy_per_key) {
54  CHECK(sd_outer_proxy_per_key);
55  sd_inner_proxy_per_key_ = sd_inner_proxy_per_key;
56  sd_outer_proxy_per_key_ = sd_outer_proxy_per_key;
57  } else
58 #endif
59  {
60  sd_inner_proxy_per_key_ = nullptr;
61  sd_outer_proxy_per_key_ = nullptr;
62  }
63  }
64 
65  template <typename T, typename KEY_BUFF_HANDLER>
66  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
67  T* key_scratch_buff,
68  KEY_BUFF_HANDLER f) const {
69  bool skip_entry = false;
70  for (size_t key_component_index = 0; key_component_index < key_component_count_;
71  ++key_component_index) {
72  const auto& join_column_iterator = join_column_iterators[key_component_index];
73  int64_t elem = (*join_column_iterator).element;
74  if (should_skip_entries_ && elem == join_column_iterator.type_info->null_val &&
75  !join_column_iterator.type_info->uses_bw_eq) {
76  skip_entry = true;
77  break;
78  }
79 #ifndef __CUDACC__
80  const auto sd_inner_proxy = sd_inner_proxy_per_key_
81  ? sd_inner_proxy_per_key_[key_component_index]
82  : nullptr;
83  const auto sd_outer_proxy = sd_outer_proxy_per_key_
84  ? sd_outer_proxy_per_key_[key_component_index]
85  : nullptr;
86  if (sd_inner_proxy && elem != join_column_iterator.type_info->null_val) {
87  CHECK(sd_outer_proxy);
88  const auto sd_inner_dict_proxy =
89  static_cast<const StringDictionaryProxy*>(sd_inner_proxy);
90  const auto sd_outer_dict_proxy =
91  static_cast<const StringDictionaryProxy*>(sd_outer_proxy);
92  const auto elem_str = sd_inner_dict_proxy->getString(elem);
93  const auto outer_id = sd_outer_dict_proxy->getIdOfString(elem_str);
94  if (outer_id == StringDictionary::INVALID_STR_ID) {
95  skip_entry = true;
96  break;
97  }
98  elem = outer_id;
99  }
100 #endif
101  key_scratch_buff[key_component_index] = elem;
102  }
103 
104  if (!skip_entry) {
105  return f(join_column_iterators[0].index, key_scratch_buff, key_component_count_);
106  }
107 
108  return 0;
109  }
110 
112 
114 
116 
118  return type_info_per_key_;
119  }
120 
121  const size_t key_component_count_;
125  const void* const* sd_inner_proxy_per_key_;
126  const void* const* sd_outer_proxy_per_key_;
127 };
128 
130  OverlapsKeyHandler(const size_t key_dims_count,
131  const JoinColumn* join_column, // always 1 column
132  const double* bucket_sizes_for_dimension)
133  : key_dims_count_(key_dims_count)
134  , join_column_(join_column)
135  , bucket_sizes_for_dimension_(bucket_sizes_for_dimension) {}
136 
137  template <typename T, typename KEY_BUFF_HANDLER>
138  DEVICE int operator()(JoinColumnIterator* join_column_iterators,
139  T* key_scratch_buff,
140  KEY_BUFF_HANDLER f) const {
141  // TODO(adb): hard-coding the 2D case w/ bounds for now. Should support n-dims with a
142  // check to ensure we are not exceeding maximum number of dims for coalesced keys
143  double bounds[4];
144  for (size_t j = 0; j < 2 * key_dims_count_; j++) {
145  bounds[j] =
146  SUFFIX(fixed_width_double_decode_noinline)(join_column_iterators->ptr(), j);
147  }
148 
149  const auto x_bucket_sz = bucket_sizes_for_dimension_[0];
150  const auto y_bucket_sz = bucket_sizes_for_dimension_[1];
151 
152  for (int64_t x = floor(bounds[0] * x_bucket_sz); x <= floor(bounds[2] * x_bucket_sz);
153  x++) {
154  for (int64_t y = floor(bounds[1] * y_bucket_sz);
155  y <= floor(bounds[3] * y_bucket_sz);
156  y++) {
157  key_scratch_buff[0] = x;
158  key_scratch_buff[1] = y;
159 
160  const auto err =
161  f(join_column_iterators[0].index, key_scratch_buff, key_dims_count_);
162  if (err) {
163  return err;
164  }
165  }
166  }
167  return 0;
168  }
169 
170  DEVICE size_t get_number_of_columns() const { return 1; }
171 
172  DEVICE size_t get_key_component_count() const { return key_dims_count_; }
173 
174  DEVICE const JoinColumn* get_join_columns() const { return join_column_; }
175 
176  DEVICE const JoinColumnTypeInfo* get_join_column_type_infos() const { return nullptr; }
177 
178  const size_t key_dims_count_;
181 };
182 
183 #endif // QUERYENGINE_HASHJOINKEYHANDLERS_H
DEVICE size_t get_key_component_count() const
const JoinColumn * join_column_per_key_
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_
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
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 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
#define CHECK(condition)
Definition: Logger.h:197
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:126
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_