OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultSetStorage Class Reference

#include <ResultSetStorage.h>

+ Collaboration diagram for ResultSetStorage:

Public Member Functions

void reduce (const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code, const size_t executor_id) const
 
void rewriteAggregateBufferOffsets (const std::vector< std::string > &serialized_varlen_buffer) const
 
int8_t * getUnderlyingBuffer () const
 
size_t getEntryCount () const
 
template<class KeyType >
void moveEntriesToBuffer (int8_t *new_buff, const size_t new_entry_count) const
 
template<class KeyType >
void moveOneEntryToBuffer (const size_t entry_index, int64_t *new_buff_i64, const size_t new_entry_count, const size_t key_count, const size_t row_qw_count, const int64_t *src_buff, const size_t key_byte_width) const
 
void updateEntryCount (const size_t new_entry_count)
 
void reduceOneApproxQuantileSlot (int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
 

Static Public Member Functions

static bool reduceSingleRow (const int8_t *row_ptr, const int8_t warp_count, const bool is_columnar, const bool replace_bitmap_ptr_with_bitmap_sz, std::vector< int64_t > &agg_vals, const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &agg_init_vals)
 

Private Member Functions

 ResultSetStorage (const std::vector< TargetInfo > &targets, const QueryMemoryDescriptor &query_mem_desc, int8_t *buff, const bool buff_is_provided)
 
void reduceEntriesNoCollisionsColWise (int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const size_t start_index, const size_t end_index, const std::vector< std::string > &serialized_varlen_buffer, const size_t executor_id) const
 
void copyKeyColWise (const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
 
bool isEmptyEntry (const size_t entry_idx, const int8_t *buff) const
 
bool isEmptyEntry (const size_t entry_idx) const
 
bool isEmptyEntryColumnar (const size_t entry_idx, const int8_t *buff) const
 
void reduceOneEntryBaseline (int8_t *this_buff, const int8_t *that_buff, const size_t i, const size_t that_entry_count, const ResultSetStorage &that) const
 
void reduceOneEntrySlotsBaseline (int64_t *this_entry_slots, const int64_t *that_buff, const size_t that_entry_idx, const size_t that_entry_count, const ResultSetStorage &that) const
 
void initializeBaselineValueSlots (int64_t *this_entry_slots) const
 
void reduceOneSlotBaseline (int64_t *this_buff, const size_t this_slot, const int64_t *that_buff, const size_t that_entry_count, const size_t that_slot, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that) const
 
ALWAYS_INLINE void reduceOneSlotSingleValue (int8_t *this_ptr1, const TargetInfo &target_info, const size_t target_slot_idx, const size_t init_agg_val_idx, const int8_t *that_ptr1) const
 
ALWAYS_INLINE void reduceOneSlot (int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
 
void reduceOneCountDistinctSlot (int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
 
void fillOneEntryRowWise (const std::vector< int64_t > &entry)
 
void fillOneEntryColWise (const std::vector< int64_t > &entry)
 
void initializeRowWise () const
 
void initializeColWise () const
 
const VarlenOutputInfogetVarlenOutputInfo () const
 
void addCountDistinctSetPointerMapping (const int64_t remote_ptr, const int64_t ptr)
 
int64_t mappedPtr (const int64_t) const
 
size_t binSearchRowCount () const
 

Private Attributes

const std::vector< TargetInfotargets_
 
QueryMemoryDescriptor query_mem_desc_
 
int8_t * buff_
 
const bool buff_is_provided_
 
std::vector< int64_t > target_init_vals_
 
std::unordered_map< int64_t,
int64_t > 
count_distinct_sets_mapping_
 
std::shared_ptr< VarlenOutputInfovarlen_output_info_
 

Friends

class ResultSet
 
class ResultSetManager
 

Detailed Description

Definition at line 96 of file ResultSetStorage.h.

Constructor & Destructor Documentation

ResultSetStorage::ResultSetStorage ( const std::vector< TargetInfo > &  targets,
const QueryMemoryDescriptor query_mem_desc,
int8_t *  buff,
const bool  buff_is_provided 
)
private

Definition at line 53 of file ResultSetStorage.cpp.

57  : targets_(targets)
58  , query_mem_desc_(query_mem_desc)
59  , buff_(buff)
60  , buff_is_provided_(buff_is_provided)
const std::vector< TargetInfo > targets_
std::vector< int64_t > target_init_vals_
const bool buff_is_provided_
std::vector< int64_t > initialize_target_values_for_storage(const std::vector< TargetInfo > &targets)
QueryMemoryDescriptor query_mem_desc_

Member Function Documentation

void ResultSetStorage::addCountDistinctSetPointerMapping ( const int64_t  remote_ptr,
const int64_t  ptr 
)
private

Definition at line 67 of file ResultSetStorage.cpp.

References CHECK, and count_distinct_sets_mapping_.

68  {
69  const auto it_ok = count_distinct_sets_mapping_.emplace(remote_ptr, ptr);
70  CHECK(it_ok.second);
71 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
#define CHECK(condition)
Definition: Logger.h:222
size_t ResultSetStorage::binSearchRowCount ( ) const
private

Definition at line 2255 of file ResultSetIteration.cpp.

References CHECK, CHECK_EQ, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_64, QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getQueryDescriptionType(), anonymous_namespace{ResultSetIteration.cpp}::make_bin_search(), Projection, ResultSet::query_mem_desc_, and row_ptr_rowwise().

2255  {
2256  // Note that table function result sets should never use this path as the row count
2257  // can be known statically (as the output buffers do not contain empty entries)
2260 
2261  if (!query_mem_desc_.getEntryCount()) {
2262  return 0;
2263  }
2264 
2266  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2267  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2268  });
2269  } else {
2270  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2271  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2272  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2273  });
2274  }
2275 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
#define EMPTY_KEY_64
size_t make_bin_search(size_t l, size_t r, T &&is_empty_fn)
size_t getEffectiveKeyWidth() const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
QueryDescriptionType getQueryDescriptionType() const
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::copyKeyColWise ( const size_t  entry_idx,
int8_t *  this_buff,
const int8_t *  that_buff 
) const
private

Definition at line 506 of file ResultSetReduction.cpp.

References CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getPrependedGroupColOffInBytes(), QueryMemoryDescriptor::groupColWidth(), and query_mem_desc_.

Referenced by reduceEntriesNoCollisionsColWise().

508  {
510  for (size_t group_idx = 0; group_idx < query_mem_desc_.getGroupbyColCount();
511  group_idx++) {
512  // if the column corresponds to a group key
513  const auto column_offset_bytes =
515  auto lhs_key_ptr = this_buff + column_offset_bytes;
516  auto rhs_key_ptr = that_buff + column_offset_bytes;
517  switch (query_mem_desc_.groupColWidth(group_idx)) {
518  case 8:
519  *(reinterpret_cast<int64_t*>(lhs_key_ptr) + entry_idx) =
520  *(reinterpret_cast<const int64_t*>(rhs_key_ptr) + entry_idx);
521  break;
522  case 4:
523  *(reinterpret_cast<int32_t*>(lhs_key_ptr) + entry_idx) =
524  *(reinterpret_cast<const int32_t*>(rhs_key_ptr) + entry_idx);
525  break;
526  case 2:
527  *(reinterpret_cast<int16_t*>(lhs_key_ptr) + entry_idx) =
528  *(reinterpret_cast<const int16_t*>(rhs_key_ptr) + entry_idx);
529  break;
530  case 1:
531  *(reinterpret_cast<int8_t*>(lhs_key_ptr) + entry_idx) =
532  *(reinterpret_cast<const int8_t*>(rhs_key_ptr) + entry_idx);
533  break;
534  default:
535  CHECK(false);
536  break;
537  }
538  }
539 }
int8_t groupColWidth(const size_t key_idx) const
size_t getGroupbyColCount() const
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::fillOneEntryColWise ( const std::vector< int64_t > &  entry)
private

Definition at line 1201 of file ResultSetReduction.cpp.

References buff_, CHECK, CHECK_EQ, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getBufferColSlotCount(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), key_offset_colwise(), query_mem_desc_, slot_offset_colwise(), and target_init_vals_.

1201  {
1203  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1204  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1205  const auto key_count = query_mem_desc_.getGroupbyColCount();
1206  CHECK_EQ(slot_count + key_count, entry.size());
1207  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1208 
1209  for (size_t i = 0; i < key_count; i++) {
1210  const auto key_offset = key_offset_colwise(0, i, 1);
1211  this_buff[key_offset] = entry[i];
1212  }
1213 
1214  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1215  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1216  this_buff[slot_offset] = entry[key_count + i];
1217  }
1218 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
std::vector< int64_t > target_init_vals_
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
size_t getGroupbyColCount() const
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::fillOneEntryRowWise ( const std::vector< int64_t > &  entry)
private

Definition at line 1148 of file ResultSetReduction.cpp.

References buff_, CHECK, CHECK_EQ, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getBufferColSlotCount(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), key_offset_rowwise(), query_mem_desc_, slot_offset_rowwise(), and target_init_vals_.

1148  {
1149  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1150  const auto key_count = query_mem_desc_.getGroupbyColCount();
1151  CHECK_EQ(slot_count + key_count, entry.size());
1152  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1154  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1155  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1156  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1157  for (size_t i = 0; i < key_count; ++i) {
1158  this_buff[key_off + i] = entry[i];
1159  }
1160  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1161  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1162  this_buff[first_slot_off + i] = entry[key_count + i];
1163  }
1164 }
size_t slot_offset_rowwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t slot_count)
#define CHECK_EQ(x, y)
Definition: Logger.h:230
std::vector< int64_t > target_init_vals_
size_t getEffectiveKeyWidth() const
size_t getGroupbyColCount() const
size_t key_offset_rowwise(const size_t entry_idx, const size_t key_count, const size_t slot_count)
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

size_t ResultSetStorage::getEntryCount ( ) const
inline

Definition at line 114 of file ResultSetStorage.h.

References QueryMemoryDescriptor::getEntryCount(), and query_mem_desc_.

114 { return query_mem_desc_.getEntryCount(); }
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

int8_t * ResultSetStorage::getUnderlyingBuffer ( ) const

Definition at line 63 of file ResultSetStorage.cpp.

References buff_.

Referenced by anonymous_namespace{Execute.cpp}::permute_storage_columnar(), and anonymous_namespace{Execute.cpp}::permute_storage_row_wise().

63  {
64  return buff_;
65 }

+ Here is the caller graph for this function:

const VarlenOutputInfo* ResultSetStorage::getVarlenOutputInfo ( ) const
inlineprivate

Definition at line 223 of file ResultSetStorage.h.

References varlen_output_info_.

223  {
224  return varlen_output_info_.get();
225  }
std::shared_ptr< VarlenOutputInfo > varlen_output_info_
void ResultSetStorage::initializeBaselineValueSlots ( int64_t *  this_entry_slots) const
private

Definition at line 1240 of file ResultSetReduction.cpp.

References CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), query_mem_desc_, and target_init_vals_.

1240  {
1241  CHECK(entry_slots);
1243  size_t slot_off = 0;
1244  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1245  entry_slots[slot_off] = target_init_vals_[j];
1246  slot_off += query_mem_desc_.getEntryCount();
1247  }
1248  } else {
1249  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1250  entry_slots[j] = target_init_vals_[j];
1251  }
1252  }
1253 }
std::vector< int64_t > target_init_vals_
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

Definition at line 1220 of file ResultSetReduction.cpp.

References buff_, CHECK, EMPTY_KEY_64, QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::hasKeylessHash(), key_offset_colwise(), query_mem_desc_, slot_offset_colwise(), and target_init_vals_.

1220  {
1221  const auto key_count = query_mem_desc_.getGroupbyColCount();
1222  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1224  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1225  const auto first_key_off =
1227  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1228  this_buff[first_key_off + i] = EMPTY_KEY_64;
1229  }
1230  }
1231  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1232  const auto first_val_off =
1233  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1234  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1235  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1236  }
1237  }
1238 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
size_t getGroupbyColCount() const
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

Definition at line 1166 of file ResultSetReduction.cpp.

References align_to_int64(), buff_, CHECK, CHECK_EQ, anonymous_namespace{ResultSetReduction.cpp}::fill_empty_key_32(), anonymous_namespace{ResultSetReduction.cpp}::fill_empty_key_64(), get_key_bytes_rowwise(), get_row_bytes(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::hasKeylessHash(), query_mem_desc_, and target_init_vals_.

1166  {
1167  const auto key_count = query_mem_desc_.getGroupbyColCount();
1168  const auto row_size = get_row_bytes(query_mem_desc_);
1169  CHECK_EQ(row_size % 8, 0u);
1170  const auto key_bytes_with_padding =
1174  case 4: {
1175  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1176  auto row_ptr = buff_ + i * row_size;
1177  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1178  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1179  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1180  slot_ptr[j] = target_init_vals_[j];
1181  }
1182  }
1183  break;
1184  }
1185  case 8: {
1186  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1187  auto row_ptr = buff_ + i * row_size;
1188  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1189  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1190  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1191  slot_ptr[j] = target_init_vals_[j];
1192  }
1193  }
1194  break;
1195  }
1196  default:
1197  CHECK(false);
1198  }
1199 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
std::vector< int64_t > target_init_vals_
size_t getEffectiveKeyWidth() const
ALWAYS_INLINE void fill_empty_key_32(int32_t *key_ptr_i32, const size_t key_count)
size_t getGroupbyColCount() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:222
ALWAYS_INLINE void fill_empty_key_64(int64_t *key_ptr_i64, const size_t key_count)
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

bool ResultSetStorage::isEmptyEntry ( const size_t  entry_idx,
const int8_t *  buff 
) const
private

Definition at line 2137 of file ResultSetIteration.cpp.

References CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_32, EMPTY_KEY_64, result_set::get_byteoff_of_slot(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), GroupByPerfectHash, QueryMemoryDescriptor::hasKeylessHash(), NonGroupedAggregate, ResultSet::query_mem_desc_, read_int_from_buff(), and row_ptr_rowwise().

Referenced by reduceOneEntryBaseline(), and rewriteAggregateBufferOffsets().

2137  {
2140  return false;
2141  }
2143  return isEmptyEntryColumnar(entry_idx, buff);
2144  }
2149  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2150  target_init_vals_.size());
2151  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2152  const auto target_slot_off = result_set::get_byteoff_of_slot(
2154  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2158  } else {
2159  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2161  case 4:
2164  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2165  case 8:
2166  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2167  default:
2168  CHECK(false);
2169  return true;
2170  }
2171  }
2172 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
#define CHECK_GE(x, y)
Definition: Logger.h:235
size_t getEffectiveKeyWidth() const
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:232
#define CHECK(condition)
Definition: Logger.h:222
#define EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
int32_t getTargetIdxForKey() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool ResultSetStorage::isEmptyEntry ( const size_t  entry_idx) const
private

Definition at line 2277 of file ResultSetIteration.cpp.

2277  {
2278  return isEmptyEntry(entry_idx, buff_);
2279 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
bool ResultSetStorage::isEmptyEntryColumnar ( const size_t  entry_idx,
const int8_t *  buff 
) const
private

Definition at line 2178 of file ResultSetIteration.cpp.

References anonymous_namespace{ResultSetIteration.cpp}::advance_col_buff_to_slot(), CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_16, EMPTY_KEY_32, EMPTY_KEY_64, EMPTY_KEY_8, QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getPrependedGroupColOffInBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), GroupByPerfectHash, QueryMemoryDescriptor::groupColWidth(), QueryMemoryDescriptor::hasKeylessHash(), NonGroupedAggregate, Projection, ResultSet::query_mem_desc_, read_int_from_buff(), TableFunction, and ResultSet::targets_.

Referenced by reduceEntriesNoCollisionsColWise().

2179  {
2183  return false;
2184  }
2186  // For table functions the entry count should always be set to the actual output size
2187  // (i.e. there are not empty entries), so just assume value is non-empty
2188  CHECK_LT(entry_idx, getEntryCount());
2189  return false;
2190  }
2195  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2196  target_init_vals_.size());
2197  const auto col_buff = advance_col_buff_to_slot(
2199  const auto entry_buff =
2200  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2202  return read_int_from_buff(entry_buff,
2206  } else {
2207  // it's enough to find the first group key which is empty
2209  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2210  } else {
2212  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2213  switch (query_mem_desc_.groupColWidth(0)) {
2214  case 8:
2215  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2216  case 4:
2217  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2218  case 2:
2219  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2220  case 1:
2221  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2222  default:
2223  CHECK(false);
2224  }
2225  }
2226  return false;
2227  }
2228  return false;
2229 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
std::vector< int64_t > target_init_vals_
#define CHECK_GE(x, y)
Definition: Logger.h:235
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
const int8_t * advance_col_buff_to_slot(const int8_t *buff, const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const size_t slot_idx, const bool separate_varlen_storage)
int8_t groupColWidth(const size_t key_idx) const
size_t getGroupbyColCount() const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define EMPTY_KEY_8
size_t getEntryCount() const
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:232
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:222
#define EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
int32_t getTargetIdxForKey() const
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int64_t ResultSetStorage::mappedPtr ( const int64_t  remote_ptr) const
private

Definition at line 73 of file ResultSetStorage.cpp.

References count_distinct_sets_mapping_.

73  {
74  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
75  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
76  // remote ptr that do not not exists. Return 0 if no pointer found
77  if (it == count_distinct_sets_mapping_.end()) {
78  return int64_t(0);
79  }
80  return it->second;
81 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
template<class KeyType >
void ResultSetStorage::moveEntriesToBuffer ( int8_t *  new_buff,
const size_t  new_entry_count 
) const

Definition at line 941 of file ResultSetReduction.cpp.

References threading_serial::async(), buff_, CHECK, CHECK_GT, cpu_threads(), anonymous_namespace{ResultSetReduction.cpp}::get_row_qw_count(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), query_mem_desc_, and anonymous_namespace{ResultSetReduction.cpp}::use_multithreaded_reduction().

942  {
944  CHECK_GT(new_entry_count, query_mem_desc_.getEntryCount());
945  auto new_buff_i64 = reinterpret_cast<int64_t*>(new_buff);
946  const auto key_count = query_mem_desc_.getGroupbyColCount();
949  const auto src_buff = reinterpret_cast<const int64_t*>(buff_);
950  const auto row_qw_count = get_row_qw_count(query_mem_desc_);
951  const auto key_byte_width = query_mem_desc_.getEffectiveKeyWidth();
952 
954  const size_t thread_count = cpu_threads();
955  std::vector<std::future<void>> move_threads;
956 
957  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
958  const auto thread_entry_count =
959  (query_mem_desc_.getEntryCount() + thread_count - 1) / thread_count;
960  const auto start_index = thread_idx * thread_entry_count;
961  const auto end_index =
962  std::min(start_index + thread_entry_count, query_mem_desc_.getEntryCount());
963  move_threads.emplace_back(std::async(
965  [this,
966  src_buff,
967  new_buff_i64,
968  new_entry_count,
969  start_index,
970  end_index,
971  key_count,
972  row_qw_count,
973  key_byte_width] {
974  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
975  moveOneEntryToBuffer<KeyType>(entry_idx,
976  new_buff_i64,
977  new_entry_count,
978  key_count,
979  row_qw_count,
980  src_buff,
981  key_byte_width);
982  }
983  }));
984  }
985  for (auto& move_thread : move_threads) {
986  move_thread.wait();
987  }
988  for (auto& move_thread : move_threads) {
989  move_thread.get();
990  }
991  } else {
992  for (size_t entry_idx = 0; entry_idx < query_mem_desc_.getEntryCount(); ++entry_idx) {
993  moveOneEntryToBuffer<KeyType>(entry_idx,
994  new_buff_i64,
995  new_entry_count,
996  key_count,
997  row_qw_count,
998  src_buff,
999  key_byte_width);
1000  }
1001  }
1002 }
size_t getEffectiveKeyWidth() const
#define CHECK_GT(x, y)
Definition: Logger.h:234
future< Result > async(Fn &&fn, Args &&...args)
size_t getGroupbyColCount() const
QueryDescriptionType getQueryDescriptionType() const
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:222
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
int cpu_threads()
Definition: thread_count.h:25
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

template<class KeyType >
void ResultSetStorage::moveOneEntryToBuffer ( const size_t  entry_index,
int64_t *  new_buff_i64,
const size_t  new_entry_count,
const size_t  key_count,
const size_t  row_qw_count,
const int64_t *  src_buff,
const size_t  key_byte_width 
) const

Definition at line 1005 of file ResultSetReduction.cpp.

References CHECK, QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::fill_slots(), get_group_value(), get_group_value_columnar(), QueryMemoryDescriptor::getEntryCount(), key_offset_colwise(), anonymous_namespace{ResultSetReduction.cpp}::make_key(), and query_mem_desc_.

1011  {
1012  const auto key_off =
1014  ? key_offset_colwise(entry_index, 0, query_mem_desc_.getEntryCount())
1015  : row_qw_count * entry_index;
1016  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
1017  if (*key_ptr == get_empty_key<KeyType>()) {
1018  return;
1019  }
1020  int64_t* new_entries_ptr{nullptr};
1022  const auto key =
1023  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
1024  new_entries_ptr =
1025  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
1026  } else {
1027  new_entries_ptr = get_group_value(new_buff_i64,
1028  new_entry_count,
1029  &src_buff[key_off],
1030  key_count,
1031  key_byte_width,
1032  row_qw_count);
1033  }
1034  CHECK(new_entries_ptr);
1035  fill_slots(new_entries_ptr,
1036  new_entry_count,
1037  src_buff,
1038  entry_index,
1040  query_mem_desc_);
1041 }
void fill_slots(int64_t *dst_entry, const size_t dst_entry_count, const int64_t *src_buff, const size_t src_entry_idx, const size_t src_entry_count, const QueryMemoryDescriptor &query_mem_desc)
std::vector< int64_t > make_key(const int64_t *buff, const size_t entry_count, const size_t key_count)
RUNTIME_EXPORT 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)
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:222
RUNTIME_EXPORT NEVER_INLINE DEVICE int64_t * get_group_value_columnar(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::reduce ( const ResultSetStorage that,
const std::vector< std::string > &  serialized_varlen_buffer,
const ReductionCode reduction_code,
const size_t  executor_id 
) const

Definition at line 203 of file ResultSetReduction.cpp.

References threading_serial::async(), buff_, CHECK, CHECK_EQ, CHECK_GE, CHECK_GT, cpu_threads(), QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, GroupByPerfectHash, ReductionCode::ir_reduce_loop, NonGroupedAggregate, query_mem_desc_, reduceOneEntryBaseline(), anonymous_namespace{ResultSetReduction.cpp}::run_reduction_code(), and anonymous_namespace{ResultSetReduction.cpp}::use_multithreaded_reduction().

Referenced by reduceOneSlotSingleValue().

206  {
207  auto entry_count = query_mem_desc_.getEntryCount();
208  CHECK_GT(entry_count, size_t(0));
216  }
217  const auto that_entry_count = that.query_mem_desc_.getEntryCount();
220  CHECK_GE(entry_count, that_entry_count);
221  break;
222  default:
223  CHECK_EQ(entry_count, that_entry_count);
224  }
225  auto this_buff = buff_;
226  CHECK(this_buff);
227  auto that_buff = that.buff_;
228  CHECK(that_buff);
231  if (!serialized_varlen_buffer.empty()) {
232  throw std::runtime_error(
233  "Projection of variable length targets with baseline hash group by is not yet "
234  "supported in Distributed mode");
235  }
236  if (use_multithreaded_reduction(that_entry_count)) {
237  const size_t thread_count = cpu_threads();
238  std::vector<std::future<void>> reduction_threads;
239  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
240  const auto thread_entry_count =
241  (that_entry_count + thread_count - 1) / thread_count;
242  const auto start_index = thread_idx * thread_entry_count;
243  const auto end_index =
244  std::min(start_index + thread_entry_count, that_entry_count);
245  reduction_threads.emplace_back(std::async(
247  [this,
248  this_buff,
249  that_buff,
250  start_index,
251  end_index,
252  that_entry_count,
253  executor_id,
254  &reduction_code,
255  &that] {
256  if (reduction_code.ir_reduce_loop) {
257  run_reduction_code(executor_id,
258  reduction_code,
259  this_buff,
260  that_buff,
261  start_index,
262  end_index,
263  that_entry_count,
265  &that.query_mem_desc_,
266  nullptr);
267  } else {
268  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
270  this_buff, that_buff, entry_idx, that_entry_count, that);
271  }
272  }
273  }));
274  }
275  for (auto& reduction_thread : reduction_threads) {
276  reduction_thread.wait();
277  }
278  for (auto& reduction_thread : reduction_threads) {
279  reduction_thread.get();
280  }
281  } else {
282  if (reduction_code.ir_reduce_loop) {
283  run_reduction_code(executor_id,
284  reduction_code,
285  this_buff,
286  that_buff,
287  0,
288  that_entry_count,
289  that_entry_count,
291  &that.query_mem_desc_,
292  nullptr);
293  } else {
294  for (size_t i = 0; i < that_entry_count; ++i) {
295  reduceOneEntryBaseline(this_buff, that_buff, i, that_entry_count, that);
296  }
297  }
298  }
299  return;
300  }
301  if (use_multithreaded_reduction(entry_count)) {
302  const size_t thread_count = cpu_threads();
303  std::vector<std::future<void>> reduction_threads;
304  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
305  const auto thread_entry_count = (entry_count + thread_count - 1) / thread_count;
306  const auto start_index = thread_idx * thread_entry_count;
307  const auto end_index = std::min(start_index + thread_entry_count, entry_count);
309  reduction_threads.emplace_back(std::async(std::launch::async,
310  [this,
311  this_buff,
312  that_buff,
313  start_index,
314  end_index,
315  &that,
316  &serialized_varlen_buffer,
317  &executor_id] {
319  this_buff,
320  that_buff,
321  that,
322  start_index,
323  end_index,
324  serialized_varlen_buffer,
325  executor_id);
326  }));
327  } else {
328  reduction_threads.emplace_back(std::async(std::launch::async,
329  [this,
330  this_buff,
331  that_buff,
332  start_index,
333  end_index,
334  that_entry_count,
335  executor_id,
336  &reduction_code,
337  &that,
338  &serialized_varlen_buffer] {
339  CHECK(reduction_code.ir_reduce_loop);
341  executor_id,
342  reduction_code,
343  this_buff,
344  that_buff,
345  start_index,
346  end_index,
347  that_entry_count,
349  &that.query_mem_desc_,
350  &serialized_varlen_buffer);
351  }));
352  }
353  }
354  for (auto& reduction_thread : reduction_threads) {
355  reduction_thread.wait();
356  }
357  for (auto& reduction_thread : reduction_threads) {
358  reduction_thread.get();
359  }
360  } else {
363  that_buff,
364  that,
365  0,
367  serialized_varlen_buffer,
368  executor_id);
369  } else {
370  CHECK(reduction_code.ir_reduce_loop);
371  run_reduction_code(executor_id,
372  reduction_code,
373  this_buff,
374  that_buff,
375  0,
376  entry_count,
377  that_entry_count,
379  &that.query_mem_desc_,
380  &serialized_varlen_buffer);
381  }
382  }
383 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
void reduceOneEntryBaseline(int8_t *this_buff, const int8_t *that_buff, const size_t i, const size_t that_entry_count, const ResultSetStorage &that) const
std::unique_ptr< Function > ir_reduce_loop
#define CHECK_GE(x, y)
Definition: Logger.h:235
#define CHECK_GT(x, y)
Definition: Logger.h:234
future< Result > async(Fn &&fn, Args &&...args)
QueryDescriptionType getQueryDescriptionType() const
void reduceEntriesNoCollisionsColWise(int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const size_t start_index, const size_t end_index, const std::vector< std::string > &serialized_varlen_buffer, const size_t executor_id) const
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:222
void run_reduction_code(const size_t executor_id, const ReductionCode &reduction_code, int8_t *this_buff, const int8_t *that_buff, const int32_t start_entry_index, const int32_t end_entry_index, const int32_t that_entry_count, const void *this_qmd, const void *that_qmd, const void *serialized_varlen_buffer)
int cpu_threads()
Definition: thread_count.h:25
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceEntriesNoCollisionsColWise ( int8_t *  this_buff,
const int8_t *  that_buff,
const ResultSetStorage that,
const size_t  start_index,
const size_t  end_index,
const std::vector< std::string > &  serialized_varlen_buffer,
const size_t  executor_id 
) const
private

Definition at line 407 of file ResultSetReduction.cpp.

References advance_to_next_columnar_target_buff(), CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog(), copyKeyColWise(), g_enable_dynamic_watchdog, g_enable_non_kernel_time_query_interrupt, get_cols_ptr(), QueryMemoryDescriptor::getColSlotContext(), Executor::getExecutor(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::hasKeylessHash(), isEmptyEntryColumnar(), kAVG, kSAMPLE, LIKELY, query_mem_desc_, reduceOneSlot(), targets_, and UNLIKELY.

414  {
415  // TODO(adb / saman): Support column wise output when serializing distributed agg
416  // functions
417  CHECK(serialized_varlen_buffer.empty());
418 
419  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
420 
421  auto this_crt_col_ptr = get_cols_ptr(this_buff, query_mem_desc_);
422  auto that_crt_col_ptr = get_cols_ptr(that_buff, query_mem_desc_);
423  auto executor = Executor::getExecutor(executor_id);
424  CHECK(executor);
425  for (size_t target_idx = 0; target_idx < targets_.size(); ++target_idx) {
426  const auto& agg_info = targets_[target_idx];
427  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_idx);
428 
429  bool two_slot_target{false};
430  if (agg_info.is_agg &&
431  (agg_info.agg_kind == kAVG ||
432  (agg_info.agg_kind == kSAMPLE && agg_info.sql_type.is_varlen()))) {
433  // Note that this assumes if one of the slot pairs in a given target is an array,
434  // all slot pairs are arrays. Currently this is true for all geo targets, but we
435  // should better codify and store this information in the future
436  two_slot_target = true;
437  }
439  executor->checkNonKernelTimeInterrupted())) {
440  throw std::runtime_error(
441  "Query execution was interrupted during result set reduction");
442  }
444  check_watchdog();
445  }
446  for (size_t target_slot_idx = slots_for_col.front();
447  target_slot_idx < slots_for_col.back() + 1;
448  target_slot_idx += 2) {
449  const auto this_next_col_ptr = advance_to_next_columnar_target_buff(
450  this_crt_col_ptr, query_mem_desc_, target_slot_idx);
451  const auto that_next_col_ptr = advance_to_next_columnar_target_buff(
452  that_crt_col_ptr, query_mem_desc_, target_slot_idx);
453  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
454  if (isEmptyEntryColumnar(entry_idx, that_buff)) {
455  continue;
456  }
458  // copy the key from right hand side
459  copyKeyColWise(entry_idx, this_buff, that_buff);
460  }
461  auto this_ptr1 =
462  this_crt_col_ptr +
463  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
464  auto that_ptr1 =
465  that_crt_col_ptr +
466  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
467  int8_t* this_ptr2{nullptr};
468  const int8_t* that_ptr2{nullptr};
469  if (UNLIKELY(two_slot_target)) {
470  this_ptr2 =
471  this_next_col_ptr +
472  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
473  that_ptr2 =
474  that_next_col_ptr +
475  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
476  }
477  reduceOneSlot(this_ptr1,
478  this_ptr2,
479  that_ptr1,
480  that_ptr2,
481  agg_info,
482  target_idx,
483  target_slot_idx,
484  target_slot_idx,
485  that,
486  slots_for_col.front(),
487  serialized_varlen_buffer);
488  }
489 
490  this_crt_col_ptr = this_next_col_ptr;
491  that_crt_col_ptr = that_next_col_ptr;
492  if (UNLIKELY(two_slot_target)) {
493  this_crt_col_ptr = advance_to_next_columnar_target_buff(
494  this_crt_col_ptr, query_mem_desc_, target_slot_idx + 1);
495  that_crt_col_ptr = advance_to_next_columnar_target_buff(
496  that_crt_col_ptr, query_mem_desc_, target_slot_idx + 1);
497  }
498  }
499  }
500 }
const std::vector< TargetInfo > targets_
ALWAYS_INLINE void reduceOneSlot(int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
T advance_to_next_columnar_target_buff(T target_ptr, const QueryMemoryDescriptor &query_mem_desc, const size_t target_slot_idx)
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:80
bool g_enable_non_kernel_time_query_interrupt
Definition: Execute.cpp:126
static std::shared_ptr< Executor > getExecutor(const ExecutorId id, const std::string &debug_dir="", const std::string &debug_file="", const SystemParameters &system_parameters=SystemParameters())
Definition: Execute.cpp:477
void copyKeyColWise(const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
#define LIKELY(x)
Definition: likely.h:24
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define UNLIKELY(x)
Definition: likely.h:25
const ColSlotContext & getColSlotContext() const
#define CHECK(condition)
Definition: Logger.h:222
T get_cols_ptr(T buff, const QueryMemoryDescriptor &query_mem_desc)
Definition: sqldefs.h:73
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::reduceOneApproxQuantileSlot ( int8_t *  this_ptr1,
const int8_t *  that_ptr1,
const size_t  target_logical_idx,
const ResultSetStorage that 
) const

Definition at line 1604 of file ResultSetReduction.cpp.

References CHECK, CHECK_LT, QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), and query_mem_desc_.

Referenced by reduceOneSlot().

1607  {
1609  static_assert(sizeof(int64_t) == sizeof(quantile::TDigest*));
1610  auto* incoming = *reinterpret_cast<quantile::TDigest* const*>(that_ptr1);
1611  CHECK(incoming) << "this_ptr1=" << (void*)this_ptr1
1612  << ", that_ptr1=" << (void const*)that_ptr1
1613  << ", target_logical_idx=" << target_logical_idx;
1614  if (incoming->centroids().capacity()) {
1615  auto* accumulator = *reinterpret_cast<quantile::TDigest**>(this_ptr1);
1616  CHECK(accumulator) << "this_ptr1=" << (void*)this_ptr1
1617  << ", that_ptr1=" << (void const*)that_ptr1
1618  << ", target_logical_idx=" << target_logical_idx;
1619  accumulator->allocate();
1620  accumulator->mergeTDigest(*incoming);
1621  }
1622 }
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:232
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneCountDistinctSlot ( int8_t *  this_ptr1,
const int8_t *  that_ptr1,
const size_t  target_logical_idx,
const ResultSetStorage that 
) const
private

Definition at line 1624 of file ResultSetReduction.cpp.

References CHECK, CHECK_LT, count_distinct_set_union(), QueryMemoryDescriptor::getCountDistinctDescriptor(), QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), Invalid, and query_mem_desc_.

Referenced by reduceOneSlot().

1627  {
1629  const auto& old_count_distinct_desc =
1630  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1631  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1632  const auto& new_count_distinct_desc =
1633  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1634  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1635  CHECK(this_ptr1 && that_ptr1);
1636  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1637  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1639  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1640 }
void count_distinct_set_union(const int64_t new_set_handle, const int64_t old_set_handle, const CountDistinctDescriptor &new_count_distinct_desc, const CountDistinctDescriptor &old_count_distinct_desc)
size_t getCountDistinctDescriptorsSize() const
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:232
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneEntryBaseline ( int8_t *  this_buff,
const int8_t *  that_buff,
const size_t  i,
const size_t  that_entry_count,
const ResultSetStorage that 
) const
private

Definition at line 830 of file ResultSetReduction.cpp.

References CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog_with_seed(), QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::fill_slots(), g_enable_dynamic_watchdog, anonymous_namespace{ResultSetReduction.cpp}::get_group_value_columnar_reduction(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), isEmptyEntry(), key_offset_colwise(), anonymous_namespace{ResultSetReduction.cpp}::make_key(), query_mem_desc_, and reduceOneEntrySlotsBaseline().

Referenced by reduce().

834  {
836  check_watchdog_with_seed(that_entry_idx);
837  }
838  const auto key_count = query_mem_desc_.getGroupbyColCount();
843  const auto key_off =
845  if (isEmptyEntry(that_entry_idx, that_buff)) {
846  return;
847  }
848  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
849  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
850  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
851  auto [this_entry_slots, empty_entry] = get_group_value_columnar_reduction(
852  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
853  CHECK(this_entry_slots);
854  if (empty_entry) {
855  fill_slots(this_entry_slots,
857  that_buff_i64,
858  that_entry_idx,
859  that_entry_count,
861  return;
862  }
864  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
865 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
ALWAYS_INLINE void check_watchdog_with_seed(const size_t sample_seed)
void fill_slots(int64_t *dst_entry, const size_t dst_entry_count, const int64_t *src_buff, const size_t src_entry_idx, const size_t src_entry_count, const QueryMemoryDescriptor &query_mem_desc)
GroupValueInfo get_group_value_columnar_reduction(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:80
std::vector< int64_t > make_key(const int64_t *buff, const size_t entry_count, const size_t key_count)
void reduceOneEntrySlotsBaseline(int64_t *this_entry_slots, const int64_t *that_buff, const size_t that_entry_idx, const size_t that_entry_count, const ResultSetStorage &that) const
size_t getGroupbyColCount() const
QueryDescriptionType getQueryDescriptionType() const
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneEntrySlotsBaseline ( int64_t *  this_entry_slots,
const int64_t *  that_buff,
const size_t  that_entry_idx,
const size_t  that_entry_count,
const ResultSetStorage that 
) const
private

Definition at line 867 of file ResultSetReduction.cpp.

References advance_slot(), CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getTargetGroupbyIndex(), query_mem_desc_, reduceOneSlotBaseline(), slot_offset_colwise(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), and targets_.

Referenced by reduceOneEntryBaseline().

871  {
873  const auto key_count = query_mem_desc_.getGroupbyColCount();
874  size_t j = 0;
875  size_t init_agg_val_idx = 0;
876  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
877  ++target_logical_idx) {
878  const auto& target_info = targets_[target_logical_idx];
879  const auto that_slot_off = slot_offset_colwise(
880  that_entry_idx, init_agg_val_idx, key_count, that_entry_count);
881  const auto this_slot_off = init_agg_val_idx * query_mem_desc_.getEntryCount();
882  reduceOneSlotBaseline(this_entry_slots,
883  this_slot_off,
884  that_buff,
885  that_entry_count,
886  that_slot_off,
887  target_info,
888  target_logical_idx,
889  j,
890  init_agg_val_idx,
891  that);
893  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
894  } else {
895  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
896  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
897  }
898  }
899  j = advance_slot(j, target_info, false);
900  }
901 }
const std::vector< TargetInfo > targets_
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
int64_t getTargetGroupbyIndex(const size_t target_idx) const
void reduceOneSlotBaseline(int64_t *this_buff, const size_t this_slot, const int64_t *that_buff, const size_t that_entry_count, const size_t that_slot, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that) const
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
size_t getGroupbyColCount() const
size_t targetGroupbyIndicesSize() const
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneSlot ( int8_t *  this_ptr1,
int8_t *  this_ptr2,
const int8_t *  that_ptr1,
const int8_t *  that_ptr2,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const ResultSetStorage that,
const size_t  first_slot_idx_for_target,
const std::vector< std::string > &  serialized_varlen_buffer 
) const
private

Definition at line 1460 of file ResultSetReduction.cpp.

References TargetInfo::agg_kind, AGGREGATE_ONE_COUNT, AGGREGATE_ONE_NULLABLE_VALUE, AGGREGATE_ONE_NULLABLE_VALUE_SMALL, CHECK, CHECK_EQ, CHECK_LT, logger::FATAL, SQLTypeInfo::get_elem_type(), result_set::get_width_for_slot(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getTargetGroupbyIndex(), TargetInfo::is_agg, is_distinct_target(), SQLTypeInfo::is_geometry(), SQLTypeInfo::is_string(), SQLTypeInfo::is_varlen(), QueryMemoryDescriptor::isLogicalSizedColumnsAllowed(), kAPPROX_COUNT_DISTINCT, kAPPROX_QUANTILE, kAVG, kCOUNT, kMAX, kMIN, kSAMPLE, kSINGLE_VALUE, kSUM, LOG, query_mem_desc_, reduceOneApproxQuantileSlot(), reduceOneCountDistinctSlot(), reduceOneSlotSingleValue(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, QueryMemoryDescriptor::targetGroupbyIndicesSize(), toString(), and UNREACHABLE.

Referenced by reduceEntriesNoCollisionsColWise(), and reduceOneSlotBaseline().

1471  {
1473  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1474  return;
1475  }
1476  }
1477  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1478  const bool float_argument_input = takes_float_argument(target_info);
1479  const auto chosen_bytes = result_set::get_width_for_slot(
1480  target_slot_idx, float_argument_input, query_mem_desc_);
1481  int64_t init_val = target_init_vals_[init_agg_val_idx]; // skip_val for nullable types
1482 
1483  if (target_info.is_agg && target_info.agg_kind == kSINGLE_VALUE) {
1485  this_ptr1, target_info, target_logical_idx, init_agg_val_idx, that_ptr1);
1486  } else if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1487  switch (target_info.agg_kind) {
1488  case kCOUNT:
1489  case kAPPROX_COUNT_DISTINCT: {
1490  if (is_distinct_target(target_info)) {
1491  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1492  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1493  break;
1494  }
1495  CHECK_EQ(int64_t(0), init_val);
1496  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1497  break;
1498  }
1499  case kAVG: {
1500  // Ignore float argument compaction for count component for fear of its overflow
1501  AGGREGATE_ONE_COUNT(this_ptr2,
1502  that_ptr2,
1503  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1504  }
1505  // fall thru
1506  case kSUM: {
1508  sum, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1509  break;
1510  }
1511  case kMIN: {
1512  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1514  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1515  } else {
1517  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1518  }
1519  break;
1520  }
1521  case kMAX: {
1522  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1524  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1525  } else {
1527  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1528  }
1529  break;
1530  }
1531  case kAPPROX_QUANTILE:
1532  CHECK_EQ(static_cast<int8_t>(sizeof(int64_t)), chosen_bytes);
1533  reduceOneApproxQuantileSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1534  break;
1535  default:
1536  UNREACHABLE() << toString(target_info.agg_kind);
1537  }
1538  } else {
1539  switch (chosen_bytes) {
1540  case 1: {
1542  const auto rhs_proj_col = *reinterpret_cast<const int8_t*>(that_ptr1);
1543  if (rhs_proj_col != init_val) {
1544  *reinterpret_cast<int8_t*>(this_ptr1) = rhs_proj_col;
1545  }
1546  break;
1547  }
1548  case 2: {
1550  const auto rhs_proj_col = *reinterpret_cast<const int16_t*>(that_ptr1);
1551  if (rhs_proj_col != init_val) {
1552  *reinterpret_cast<int16_t*>(this_ptr1) = rhs_proj_col;
1553  }
1554  break;
1555  }
1556  case 4: {
1557  CHECK(target_info.agg_kind != kSAMPLE ||
1559  const auto rhs_proj_col = *reinterpret_cast<const int32_t*>(that_ptr1);
1560  if (rhs_proj_col != init_val) {
1561  *reinterpret_cast<int32_t*>(this_ptr1) = rhs_proj_col;
1562  }
1563  break;
1564  }
1565  case 8: {
1566  auto rhs_proj_col = *reinterpret_cast<const int64_t*>(that_ptr1);
1567  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) &&
1568  !serialized_varlen_buffer.empty()) {
1569  size_t length_to_elems{0};
1570  if (target_info.sql_type.is_geometry()) {
1571  // TODO: Assumes hard-coded sizes for geometry targets
1572  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1573  } else {
1574  const auto& elem_ti = target_info.sql_type.get_elem_type();
1575  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1576  }
1577 
1578  CHECK_LT(static_cast<size_t>(rhs_proj_col), serialized_varlen_buffer.size());
1579  const auto& varlen_bytes_str = serialized_varlen_buffer[rhs_proj_col];
1580  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
1581  *reinterpret_cast<int64_t*>(this_ptr1) =
1582  reinterpret_cast<const int64_t>(str_ptr);
1583  *reinterpret_cast<int64_t*>(this_ptr2) =
1584  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
1585  } else {
1586  if (rhs_proj_col != init_val) {
1587  *reinterpret_cast<int64_t*>(this_ptr1) = rhs_proj_col;
1588  }
1589  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen())) {
1590  CHECK(this_ptr2 && that_ptr2);
1591  *reinterpret_cast<int64_t*>(this_ptr2) =
1592  *reinterpret_cast<const int64_t*>(that_ptr2);
1593  }
1594  }
1595 
1596  break;
1597  }
1598  default:
1599  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1600  }
1601  }
1602 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
std::vector< int64_t > target_init_vals_
int64_t getTargetGroupbyIndex(const size_t target_idx) const
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:52
#define LOG(tag)
Definition: Logger.h:216
bool is_varlen() const
Definition: sqltypes.h:640
#define UNREACHABLE()
Definition: Logger.h:266
void reduceOneApproxQuantileSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
std::string toString(const QueryDescriptionType &type)
Definition: Types.h:64
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:111
Definition: sqldefs.h:74
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
bool is_agg
Definition: TargetInfo.h:50
void reduceOneCountDistinctSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
size_t targetGroupbyIndicesSize() const
Definition: sqldefs.h:76
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:107
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
SQLAgg agg_kind
Definition: TargetInfo.h:51
#define AGGREGATE_ONE_NULLABLE_VALUE(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK_LT(x, y)
Definition: Logger.h:232
ALWAYS_INLINE void reduceOneSlotSingleValue(int8_t *this_ptr1, const TargetInfo &target_info, const size_t target_slot_idx, const size_t init_agg_val_idx, const int8_t *that_ptr1) const
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:77
#define CHECK(condition)
Definition: Logger.h:222
bool is_geometry() const
Definition: sqltypes.h:612
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
bool is_string() const
Definition: sqltypes.h:600
Definition: sqldefs.h:75
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:981
Definition: sqldefs.h:73
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneSlotBaseline ( int64_t *  this_buff,
const size_t  this_slot,
const int64_t *  that_buff,
const size_t  that_entry_count,
const size_t  that_slot,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const ResultSetStorage that 
) const
private

Definition at line 903 of file ResultSetReduction.cpp.

References TargetInfo::agg_kind, CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), TargetInfo::is_agg, SQLTypeInfo::is_varlen(), kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), and TargetInfo::sql_type.

Referenced by reduceOneEntrySlotsBaseline().

912  {
914  int8_t* this_ptr2{nullptr};
915  const int8_t* that_ptr2{nullptr};
916  if (target_info.is_agg &&
917  (target_info.agg_kind == kAVG ||
918  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
919  const auto this_count_off = query_mem_desc_.getEntryCount();
920  const auto that_count_off = that_entry_count;
921  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
922  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
923  }
924  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
925  this_ptr2,
926  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
927  that_ptr2,
928  target_info,
929  target_logical_idx,
930  target_slot_idx,
931  init_agg_val_idx,
932  that,
933  target_slot_idx, // dummy, for now
934  {});
935 }
ALWAYS_INLINE void reduceOneSlot(int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
SQLTypeInfo sql_type
Definition: TargetInfo.h:52
bool is_varlen() const
Definition: sqltypes.h:640
bool is_agg
Definition: TargetInfo.h:50
SQLAgg agg_kind
Definition: TargetInfo.h:51
#define CHECK(condition)
Definition: Logger.h:222
Definition: sqldefs.h:73
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneSlotSingleValue ( int8_t *  this_ptr1,
const TargetInfo target_info,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const int8_t *  that_ptr1 
) const
private

Definition at line 1412 of file ResultSetReduction.cpp.

References CHECK, logger::FATAL, result_set::get_width_for_slot(), SQLTypeInfo::is_varlen(), QueryMemoryDescriptor::isLogicalSizedColumnsAllowed(), LOG, query_mem_desc_, reduce(), TargetInfo::sql_type, takes_float_argument(), and target_init_vals_.

Referenced by reduceOneSlot().

1416  {
1417  const bool float_argument_input = takes_float_argument(target_info);
1418  const auto chosen_bytes = result_set::get_width_for_slot(
1419  target_slot_idx, float_argument_input, query_mem_desc_);
1420  auto init_val = target_init_vals_[init_agg_val_idx];
1421 
1422  auto reduce = [&](auto const& size_tag) {
1423  using CastTarget = std::decay_t<decltype(size_tag)>;
1424  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1425  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1426  if (rhs_proj_col == init_val) {
1427  // ignore
1428  } else if (lhs_proj_col == init_val) {
1429  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1430  } else if (lhs_proj_col != rhs_proj_col) {
1431  throw std::runtime_error("Multiple distinct values encountered");
1432  }
1433  };
1434 
1435  switch (chosen_bytes) {
1436  case 1: {
1438  reduce(int8_t());
1439  break;
1440  }
1441  case 2: {
1443  reduce(int16_t());
1444  break;
1445  }
1446  case 4: {
1447  reduce(int32_t());
1448  break;
1449  }
1450  case 8: {
1451  CHECK(!target_info.sql_type.is_varlen());
1452  reduce(int64_t());
1453  break;
1454  }
1455  default:
1456  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1457  }
1458 }
std::vector< int64_t > target_init_vals_
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:52
#define LOG(tag)
Definition: Logger.h:216
bool is_varlen() const
Definition: sqltypes.h:640
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:111
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
void reduce(const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code, const size_t executor_id) const
#define CHECK(condition)
Definition: Logger.h:222
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool ResultSetStorage::reduceSingleRow ( const int8_t *  row_ptr,
const int8_t  warp_count,
const bool  is_columnar,
const bool  replace_bitmap_ptr_with_bitmap_sz,
std::vector< int64_t > &  agg_vals,
const QueryMemoryDescriptor query_mem_desc,
const std::vector< TargetInfo > &  targets,
const std::vector< int64_t > &  agg_init_vals 
)
static

Definition at line 1642 of file ResultSetReduction.cpp.

References AGGREGATE_ONE_COUNT, AGGREGATE_ONE_NULLABLE_COUNT, AGGREGATE_ONE_NULLABLE_VALUE, AGGREGATE_ONE_NULLABLE_VALUE_SMALL, CHECK, CHECK_EQ, CHECK_GE, count_distinct_set_size(), QueryMemoryDescriptor::didOutputColumnar(), logger::ERROR, get_compact_type(), anonymous_namespace{ResultSetReduction.cpp}::get_component(), QueryMemoryDescriptor::getColOnlyOffInBytes(), QueryMemoryDescriptor::getCountDistinctDescriptor(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getRowSize(), QueryMemoryDescriptor::getSlotCount(), QueryMemoryDescriptor::getTargetIdxForKey(), QueryMemoryDescriptor::hasKeylessHash(), is_distinct_target(), kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kMAX, kMIN, kSAMPLE, kSUM, LOG, and takes_float_argument().

Referenced by QueryExecutionContext::groupBufferToDeinterleavedResults().

1649  {
1650  const size_t agg_col_count{agg_vals.size()};
1651  const auto row_size = query_mem_desc.getRowSize();
1652  CHECK_EQ(agg_col_count, query_mem_desc.getSlotCount());
1653  CHECK_GE(agg_col_count, targets.size());
1654  CHECK_EQ(is_columnar, query_mem_desc.didOutputColumnar());
1655  CHECK(query_mem_desc.hasKeylessHash());
1656  std::vector<int64_t> partial_agg_vals(agg_col_count, 0);
1657  bool discard_row = true;
1658  for (int8_t warp_idx = 0; warp_idx < warp_count; ++warp_idx) {
1659  bool discard_partial_result = true;
1660  for (size_t target_idx = 0, agg_col_idx = 0;
1661  target_idx < targets.size() && agg_col_idx < agg_col_count;
1662  ++target_idx, ++agg_col_idx) {
1663  const auto& agg_info = targets[target_idx];
1664  const bool float_argument_input = takes_float_argument(agg_info);
1665  const auto chosen_bytes = float_argument_input
1666  ? sizeof(float)
1667  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1668  auto partial_bin_val = get_component(
1669  row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx), chosen_bytes);
1670  partial_agg_vals[agg_col_idx] = partial_bin_val;
1671  if (is_distinct_target(agg_info)) {
1672  CHECK_EQ(int8_t(1), warp_count);
1673  CHECK(agg_info.is_agg && (agg_info.agg_kind == kCOUNT ||
1674  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1675  partial_bin_val = count_distinct_set_size(
1676  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1677  if (replace_bitmap_ptr_with_bitmap_sz) {
1678  partial_agg_vals[agg_col_idx] = partial_bin_val;
1679  }
1680  }
1681  if (kAVG == agg_info.agg_kind) {
1682  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1683  ++agg_col_idx;
1684  partial_bin_val = partial_agg_vals[agg_col_idx] =
1685  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1686  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1687  }
1688  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1689  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1690  CHECK(agg_info.is_agg);
1691  discard_partial_result = false;
1692  }
1693  }
1694  row_ptr += row_size;
1695  if (discard_partial_result) {
1696  continue;
1697  }
1698  discard_row = false;
1699  for (size_t target_idx = 0, agg_col_idx = 0;
1700  target_idx < targets.size() && agg_col_idx < agg_col_count;
1701  ++target_idx, ++agg_col_idx) {
1702  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1703  const auto& agg_info = targets[target_idx];
1704  const bool float_argument_input = takes_float_argument(agg_info);
1705  const auto chosen_bytes = float_argument_input
1706  ? sizeof(float)
1707  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1708  const auto& chosen_type = get_compact_type(agg_info);
1709  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1710  try {
1711  switch (agg_info.agg_kind) {
1712  case kCOUNT:
1715  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1716  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1717  agg_init_vals[agg_col_idx],
1718  chosen_bytes,
1719  agg_info);
1720  break;
1721  case kAVG:
1722  // Ignore float argument compaction for count component for fear of its
1723  // overflow
1725  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1726  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1727  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1728  // fall thru
1729  case kSUM:
1731  sum,
1732  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1733  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1734  agg_init_vals[agg_col_idx],
1735  chosen_bytes,
1736  agg_info);
1737  break;
1738  case kMIN:
1739  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1741  min,
1742  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1743  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1744  agg_init_vals[agg_col_idx],
1745  chosen_bytes,
1746  agg_info);
1747  } else {
1749  min,
1750  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1751  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1752  agg_init_vals[agg_col_idx],
1753  chosen_bytes,
1754  agg_info);
1755  }
1756  break;
1757  case kMAX:
1758  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1760  max,
1761  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1762  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1763  agg_init_vals[agg_col_idx],
1764  chosen_bytes,
1765  agg_info);
1766  } else {
1768  max,
1769  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1770  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1771  agg_init_vals[agg_col_idx],
1772  chosen_bytes,
1773  agg_info);
1774  }
1775  break;
1776  default:
1777  CHECK(false);
1778  break;
1779  }
1780  } catch (std::runtime_error& e) {
1781  // TODO(miyu): handle the case where chosen_bytes < 8
1782  LOG(ERROR) << e.what();
1783  }
1784  if (chosen_type.is_integer() || chosen_type.is_decimal()) {
1785  switch (chosen_bytes) {
1786  case 8:
1787  break;
1788  case 4: {
1789  int32_t ret = *reinterpret_cast<const int32_t*>(&agg_vals[agg_col_idx]);
1790  if (!(agg_info.agg_kind == kCOUNT && ret != agg_init_vals[agg_col_idx])) {
1791  agg_vals[agg_col_idx] = static_cast<int64_t>(ret);
1792  }
1793  break;
1794  }
1795  default:
1796  CHECK(false);
1797  }
1798  }
1799  if (kAVG == agg_info.agg_kind) {
1800  ++agg_col_idx;
1801  }
1802  } else {
1803  if (agg_info.agg_kind == kSAMPLE) {
1804  CHECK(!agg_info.sql_type.is_varlen())
1805  << "Interleaved bins reduction not supported for variable length "
1806  "arguments "
1807  "to SAMPLE";
1808  }
1809  if (agg_vals[agg_col_idx]) {
1810  if (agg_info.agg_kind == kSAMPLE) {
1811  continue;
1812  }
1813  CHECK_EQ(agg_vals[agg_col_idx], partial_bin_val);
1814  } else {
1815  agg_vals[agg_col_idx] = partial_bin_val;
1816  }
1817  }
1818  }
1819  }
1820  return discard_row;
1821 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
int64_t get_component(const int8_t *group_by_buffer, const size_t comp_sz, const size_t index=0)
#define LOG(tag)
Definition: Logger.h:216
#define CHECK_GE(x, y)
Definition: Logger.h:235
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:111
size_t getColOnlyOffInBytes(const size_t col_idx) const
Definition: sqldefs.h:74
const SQLTypeInfo get_compact_type(const TargetInfo &target)
int64_t count_distinct_set_size(const int64_t set_handle, const CountDistinctDescriptor &count_distinct_desc)
Definition: CountDistinct.h:75
Definition: sqldefs.h:76
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:107
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define AGGREGATE_ONE_NULLABLE_VALUE(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:77
#define AGGREGATE_ONE_NULLABLE_COUNT(val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK(condition)
Definition: Logger.h:222
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
Definition: sqldefs.h:75
Definition: sqldefs.h:73
int32_t getTargetIdxForKey() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::rewriteAggregateBufferOffsets ( const std::vector< std::string > &  serialized_varlen_buffer) const

Definition at line 543 of file ResultSetReduction.cpp.

References advance_slot(), advance_target_ptr_row_wise(), align_to_int64(), buff_, CHECK, CHECK_GT, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), get_key_bytes_rowwise(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), isEmptyEntry(), kSAMPLE, query_mem_desc_, row_ptr_rowwise(), and targets_.

544  {
545  if (serialized_varlen_buffer.empty()) {
546  return;
547  }
548 
550  auto entry_count = query_mem_desc_.getEntryCount();
551  CHECK_GT(entry_count, size_t(0));
552  CHECK(buff_);
553 
554  // Row-wise iteration, consider moving to separate function
555  for (size_t i = 0; i < entry_count; ++i) {
556  if (isEmptyEntry(i, buff_)) {
557  continue;
558  }
559  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
560  const auto key_bytes_with_padding = align_to_int64(key_bytes);
561  auto rowwise_targets_ptr =
562  row_ptr_rowwise(buff_, query_mem_desc_, i) + key_bytes_with_padding;
563  size_t target_slot_idx = 0;
564  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
565  ++target_logical_idx) {
566  const auto& target_info = targets_[target_logical_idx];
567  if (target_info.sql_type.is_varlen() && target_info.is_agg) {
568  CHECK(target_info.agg_kind == kSAMPLE);
569  auto ptr1 = rowwise_targets_ptr;
570  auto slot_idx = target_slot_idx;
571  auto ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
572  auto offset = *reinterpret_cast<const int64_t*>(ptr1);
573 
574  const auto& elem_ti = target_info.sql_type.get_elem_type();
575  size_t length_to_elems =
576  target_info.sql_type.is_string() || target_info.sql_type.is_geometry()
577  ? 1
578  : elem_ti.get_size();
579  if (target_info.sql_type.is_geometry()) {
580  for (int j = 0; j < target_info.sql_type.get_physical_coord_cols(); j++) {
581  if (j > 0) {
582  ptr1 = ptr2 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 1);
583  ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 2);
584  slot_idx += 2;
585  length_to_elems = 4;
586  }
587  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
588  const auto& varlen_bytes_str = serialized_varlen_buffer[offset++];
589  const auto str_ptr =
590  reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
591  CHECK(ptr1);
592  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
593  CHECK(ptr2);
594  *reinterpret_cast<int64_t*>(ptr2) =
595  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
596  }
597  } else {
598  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
599  const auto& varlen_bytes_str = serialized_varlen_buffer[offset];
600  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
601  CHECK(ptr1);
602  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
603  CHECK(ptr2);
604  *reinterpret_cast<int64_t*>(ptr2) =
605  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
606  }
607  }
608 
609  rowwise_targets_ptr = advance_target_ptr_row_wise(
610  rowwise_targets_ptr, target_info, target_slot_idx, query_mem_desc_, false);
611  target_slot_idx = advance_slot(target_slot_idx, target_info, false);
612  }
613  }
614 
615  return;
616 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
const std::vector< TargetInfo > targets_
T advance_target_ptr_row_wise(T target_ptr, const TargetInfo &target_info, const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc, const bool separate_varlen_storage)
#define CHECK_GT(x, y)
Definition: Logger.h:234
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
#define CHECK_LT(x, y)
Definition: Logger.h:232
#define CHECK(condition)
Definition: Logger.h:222
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::updateEntryCount ( const size_t  new_entry_count)
inline

Definition at line 128 of file ResultSetStorage.h.

References query_mem_desc_, and QueryMemoryDescriptor::setEntryCount().

128  {
129  query_mem_desc_.setEntryCount(new_entry_count);
130  }
void setEntryCount(const size_t val)
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

Friends And Related Function Documentation

friend class ResultSet
friend

Definition at line 250 of file ResultSetStorage.h.

friend class ResultSetManager
friend

Definition at line 251 of file ResultSetStorage.h.

Member Data Documentation

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 238 of file ResultSetStorage.h.

std::unordered_map<int64_t, int64_t> ResultSetStorage::count_distinct_sets_mapping_
private

Definition at line 245 of file ResultSetStorage.h.

Referenced by addCountDistinctSetPointerMapping(), and mappedPtr().

std::vector<int64_t> ResultSetStorage::target_init_vals_
private
const std::vector<TargetInfo> ResultSetStorage::targets_
private
std::shared_ptr<VarlenOutputInfo> ResultSetStorage::varlen_output_info_
private

Definition at line 248 of file ResultSetStorage.h.

Referenced by getVarlenOutputInfo().


The documentation for this class was generated from the following files: