OmniSciDB  72c90bc290
 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:291
size_t ResultSetStorage::binSearchRowCount ( ) const
private

Definition at line 2572 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().

2572  {
2573  // Note that table function result sets should never use this path as the row count
2574  // can be known statically (as the output buffers do not contain empty entries)
2577 
2578  if (!query_mem_desc_.getEntryCount()) {
2579  return 0;
2580  }
2581 
2583  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2584  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2585  });
2586  } else {
2587  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2588  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2589  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2590  });
2591  }
2592 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
#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:291
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:291
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 1196 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_.

1196  {
1198  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1199  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1200  const auto key_count = query_mem_desc_.getGroupbyColCount();
1201  CHECK_EQ(slot_count + key_count, entry.size());
1202  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1203 
1204  for (size_t i = 0; i < key_count; i++) {
1205  const auto key_offset = key_offset_colwise(0, i, 1);
1206  this_buff[key_offset] = entry[i];
1207  }
1208 
1209  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1210  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1211  this_buff[slot_offset] = entry[key_count + i];
1212  }
1213 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:291
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 1143 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_.

1143  {
1144  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1145  const auto key_count = query_mem_desc_.getGroupbyColCount();
1146  CHECK_EQ(slot_count + key_count, entry.size());
1147  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1149  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1150  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1151  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1152  for (size_t i = 0; i < key_count; ++i) {
1153  this_buff[key_off + i] = entry[i];
1154  }
1155  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1156  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1157  this_buff[first_slot_off + i] = entry[key_count + i];
1158  }
1159 }
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:301
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:291
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 1235 of file ResultSetReduction.cpp.

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

1235  {
1236  CHECK(entry_slots);
1238  size_t slot_off = 0;
1239  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1240  entry_slots[slot_off] = target_init_vals_[j];
1241  slot_off += query_mem_desc_.getEntryCount();
1242  }
1243  } else {
1244  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1245  entry_slots[j] = target_init_vals_[j];
1246  }
1247  }
1248 }
std::vector< int64_t > target_init_vals_
#define CHECK(condition)
Definition: Logger.h:291
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

Definition at line 1215 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_.

1215  {
1216  const auto key_count = query_mem_desc_.getGroupbyColCount();
1217  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1219  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1220  const auto first_key_off =
1222  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1223  this_buff[first_key_off + i] = EMPTY_KEY_64;
1224  }
1225  }
1226  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1227  const auto first_val_off =
1228  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1229  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1230  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1231  }
1232  }
1233 }
#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:291
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

Definition at line 1161 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_.

1161  {
1162  const auto key_count = query_mem_desc_.getGroupbyColCount();
1163  const auto row_size = get_row_bytes(query_mem_desc_);
1164  CHECK_EQ(row_size % 8, 0u);
1165  const auto key_bytes_with_padding =
1169  case 4: {
1170  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1171  auto row_ptr = buff_ + i * row_size;
1172  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1173  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1174  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1175  slot_ptr[j] = target_init_vals_[j];
1176  }
1177  }
1178  break;
1179  }
1180  case 8: {
1181  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1182  auto row_ptr = buff_ + i * row_size;
1183  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1184  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1185  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1186  slot_ptr[j] = target_init_vals_[j];
1187  }
1188  }
1189  break;
1190  }
1191  default:
1192  CHECK(false);
1193  }
1194 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:291
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 2454 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().

2454  {
2457  return false;
2458  }
2460  return isEmptyEntryColumnar(entry_idx, buff);
2461  }
2466  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2467  target_init_vals_.size());
2468  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2469  const auto target_slot_off = result_set::get_byteoff_of_slot(
2471  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2475  } else {
2476  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2478  case 4:
2481  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2482  case 8:
2483  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2484  default:
2485  CHECK(false);
2486  return true;
2487  }
2488  }
2489 }
#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:306
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:303
#define CHECK(condition)
Definition: Logger.h:291
#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 2594 of file ResultSetIteration.cpp.

2594  {
2595  return isEmptyEntry(entry_idx, buff_);
2596 }
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 2495 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().

2496  {
2500  return false;
2501  }
2503  // For table functions the entry count should always be set to the actual output size
2504  // (i.e. there are not empty entries), so just assume value is non-empty
2505  CHECK_LT(entry_idx, getEntryCount());
2506  return false;
2507  }
2512  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2513  target_init_vals_.size());
2514  const auto col_buff = advance_col_buff_to_slot(
2516  const auto entry_buff =
2517  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2519  return read_int_from_buff(entry_buff,
2523  } else {
2524  // it's enough to find the first group key which is empty
2526  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2527  } else {
2529  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2530  switch (query_mem_desc_.groupColWidth(0)) {
2531  case 8:
2532  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2533  case 4:
2534  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2535  case 2:
2536  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2537  case 1:
2538  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2539  default:
2540  CHECK(false);
2541  }
2542  }
2543  return false;
2544  }
2545  return false;
2546 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
std::vector< int64_t > target_init_vals_
#define CHECK_GE(x, y)
Definition: Logger.h:306
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:303
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:291
#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:305
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:291
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:291
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:301
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:306
#define CHECK_GT(x, y)
Definition: Logger.h:305
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:291
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:81
bool g_enable_non_kernel_time_query_interrupt
Definition: Execute.cpp:134
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:509
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:291
T get_cols_ptr(T buff, const QueryMemoryDescriptor &query_mem_desc)
Definition: sqldefs.h:74
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 1601 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlot().

1604  {
1606  static_assert(sizeof(int64_t) == sizeof(quantile::TDigest*));
1607  auto* incoming = *reinterpret_cast<quantile::TDigest* const*>(that_ptr1);
1608  CHECK(incoming) << "this_ptr1=" << (void*)this_ptr1
1609  << ", that_ptr1=" << (void const*)that_ptr1
1610  << ", target_logical_idx=" << target_logical_idx;
1611  if (incoming->centroids().capacity()) {
1612  auto* accumulator = *reinterpret_cast<quantile::TDigest**>(this_ptr1);
1613  CHECK(accumulator) << "this_ptr1=" << (void*)this_ptr1
1614  << ", that_ptr1=" << (void const*)that_ptr1
1615  << ", target_logical_idx=" << target_logical_idx;
1616  accumulator->allocate();
1617  accumulator->mergeTDigest(*incoming);
1618  }
1619 }
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
#define CHECK(condition)
Definition: Logger.h:291
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 1621 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlot().

1624  {
1626  const auto& old_count_distinct_desc =
1627  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1628  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1629  const auto& new_count_distinct_desc =
1630  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1631  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1632  CHECK(this_ptr1 && that_ptr1);
1633  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1634  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1636  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1637 }
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:303
#define CHECK(condition)
Definition: Logger.h:291
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:81
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:291
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:291
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 1455 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, kCOUNT_IF, kMAX, kMIN, kSAMPLE, kSINGLE_VALUE, kSUM, kSUM_IF, 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().

1466  {
1468  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1469  return;
1470  }
1471  }
1472  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1473  const bool float_argument_input = takes_float_argument(target_info);
1474  const auto chosen_bytes = result_set::get_width_for_slot(
1475  target_slot_idx, float_argument_input, query_mem_desc_);
1476  int64_t init_val = target_init_vals_[init_agg_val_idx]; // skip_val for nullable types
1477 
1478  if (target_info.is_agg && target_info.agg_kind == kSINGLE_VALUE) {
1480  this_ptr1, target_info, target_logical_idx, init_agg_val_idx, that_ptr1);
1481  } else if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1482  switch (target_info.agg_kind) {
1483  case kCOUNT:
1484  case kCOUNT_IF:
1485  case kAPPROX_COUNT_DISTINCT: {
1486  if (is_distinct_target(target_info)) {
1487  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1488  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1489  break;
1490  }
1491  CHECK_EQ(int64_t(0), init_val);
1492  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1493  break;
1494  }
1495  case kAVG: {
1496  // Ignore float argument compaction for count component for fear of its overflow
1497  AGGREGATE_ONE_COUNT(this_ptr2,
1498  that_ptr2,
1499  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1500  }
1501  // fall thru
1502  case kSUM:
1503  case kSUM_IF: {
1505  sum, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1506  break;
1507  }
1508  case kMIN: {
1509  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1511  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1512  } else {
1514  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1515  }
1516  break;
1517  }
1518  case kMAX: {
1519  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1521  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1522  } else {
1524  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1525  }
1526  break;
1527  }
1528  case kAPPROX_QUANTILE:
1529  CHECK_EQ(static_cast<int8_t>(sizeof(int64_t)), chosen_bytes);
1530  reduceOneApproxQuantileSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1531  break;
1532  default:
1533  UNREACHABLE() << toString(target_info.agg_kind);
1534  }
1535  } else {
1536  switch (chosen_bytes) {
1537  case 1: {
1539  const auto rhs_proj_col = *reinterpret_cast<const int8_t*>(that_ptr1);
1540  if (rhs_proj_col != init_val) {
1541  *reinterpret_cast<int8_t*>(this_ptr1) = rhs_proj_col;
1542  }
1543  break;
1544  }
1545  case 2: {
1547  const auto rhs_proj_col = *reinterpret_cast<const int16_t*>(that_ptr1);
1548  if (rhs_proj_col != init_val) {
1549  *reinterpret_cast<int16_t*>(this_ptr1) = rhs_proj_col;
1550  }
1551  break;
1552  }
1553  case 4: {
1554  CHECK(target_info.agg_kind != kSAMPLE ||
1556  const auto rhs_proj_col = *reinterpret_cast<const int32_t*>(that_ptr1);
1557  if (rhs_proj_col != init_val) {
1558  *reinterpret_cast<int32_t*>(this_ptr1) = rhs_proj_col;
1559  }
1560  break;
1561  }
1562  case 8: {
1563  auto rhs_proj_col = *reinterpret_cast<const int64_t*>(that_ptr1);
1564  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) &&
1565  !serialized_varlen_buffer.empty()) {
1566  size_t length_to_elems{0};
1567  if (target_info.sql_type.is_geometry()) {
1568  // TODO: Assumes hard-coded sizes for geometry targets
1569  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1570  } else {
1571  const auto& elem_ti = target_info.sql_type.get_elem_type();
1572  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1573  }
1574 
1575  CHECK_LT(static_cast<size_t>(rhs_proj_col), serialized_varlen_buffer.size());
1576  const auto& varlen_bytes_str = serialized_varlen_buffer[rhs_proj_col];
1577  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
1578  *reinterpret_cast<int64_t*>(this_ptr1) =
1579  reinterpret_cast<const int64_t>(str_ptr);
1580  *reinterpret_cast<int64_t*>(this_ptr2) =
1581  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
1582  } else {
1583  if (rhs_proj_col != init_val) {
1584  *reinterpret_cast<int64_t*>(this_ptr1) = rhs_proj_col;
1585  }
1586  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen())) {
1587  CHECK(this_ptr2 && that_ptr2);
1588  *reinterpret_cast<int64_t*>(this_ptr2) =
1589  *reinterpret_cast<const int64_t*>(that_ptr2);
1590  }
1591  }
1592 
1593  break;
1594  }
1595  default:
1596  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1597  }
1598  }
1599 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:285
bool is_varlen() const
Definition: sqltypes.h:629
#define UNREACHABLE()
Definition: Logger.h:338
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:106
Definition: sqldefs.h:75
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:77
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:102
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:303
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:78
#define CHECK(condition)
Definition: Logger.h:291
bool is_geometry() const
Definition: sqltypes.h:595
#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:559
Definition: sqldefs.h:76
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:975
Definition: sqldefs.h:74
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:629
bool is_agg
Definition: TargetInfo.h:50
SQLAgg agg_kind
Definition: TargetInfo.h:51
#define CHECK(condition)
Definition: Logger.h:291
Definition: sqldefs.h:74
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 1407 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().

1411  {
1412  const bool float_argument_input = takes_float_argument(target_info);
1413  const auto chosen_bytes = result_set::get_width_for_slot(
1414  target_slot_idx, float_argument_input, query_mem_desc_);
1415  auto init_val = target_init_vals_[init_agg_val_idx];
1416 
1417  auto reduce = [&](auto const& size_tag) {
1418  using CastTarget = std::decay_t<decltype(size_tag)>;
1419  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1420  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1421  if (rhs_proj_col == init_val) {
1422  // ignore
1423  } else if (lhs_proj_col == init_val) {
1424  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1425  } else if (lhs_proj_col != rhs_proj_col) {
1426  throw std::runtime_error("Multiple distinct values encountered");
1427  }
1428  };
1429 
1430  switch (chosen_bytes) {
1431  case 1: {
1433  reduce(int8_t());
1434  break;
1435  }
1436  case 2: {
1438  reduce(int16_t());
1439  break;
1440  }
1441  case 4: {
1442  reduce(int32_t());
1443  break;
1444  }
1445  case 8: {
1446  CHECK(!target_info.sql_type.is_varlen());
1447  reduce(int64_t());
1448  break;
1449  }
1450  default:
1451  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1452  }
1453 }
std::vector< int64_t > target_init_vals_
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:52
#define LOG(tag)
Definition: Logger.h:285
bool is_varlen() const
Definition: sqltypes.h:629
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
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:291
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 1639 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, kCOUNT_IF, kMAX, kMIN, kSAMPLE, kSUM, kSUM_IF, LOG, and takes_float_argument().

Referenced by QueryExecutionContext::groupBufferToDeinterleavedResults().

1646  {
1647  const size_t agg_col_count{agg_vals.size()};
1648  const auto row_size = query_mem_desc.getRowSize();
1649  CHECK_EQ(agg_col_count, query_mem_desc.getSlotCount());
1650  CHECK_GE(agg_col_count, targets.size());
1651  CHECK_EQ(is_columnar, query_mem_desc.didOutputColumnar());
1652  CHECK(query_mem_desc.hasKeylessHash());
1653  std::vector<int64_t> partial_agg_vals(agg_col_count, 0);
1654  bool discard_row = true;
1655  for (int8_t warp_idx = 0; warp_idx < warp_count; ++warp_idx) {
1656  bool discard_partial_result = true;
1657  for (size_t target_idx = 0, agg_col_idx = 0;
1658  target_idx < targets.size() && agg_col_idx < agg_col_count;
1659  ++target_idx, ++agg_col_idx) {
1660  const auto& agg_info = targets[target_idx];
1661  const bool float_argument_input = takes_float_argument(agg_info);
1662  const auto chosen_bytes = float_argument_input
1663  ? sizeof(float)
1664  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1665  auto partial_bin_val = get_component(
1666  row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx), chosen_bytes);
1667  partial_agg_vals[agg_col_idx] = partial_bin_val;
1668  if (is_distinct_target(agg_info)) {
1669  CHECK_EQ(int8_t(1), warp_count);
1670  CHECK(agg_info.is_agg &&
1671  (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kCOUNT_IF ||
1672  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1673  partial_bin_val = count_distinct_set_size(
1674  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1675  if (replace_bitmap_ptr_with_bitmap_sz) {
1676  partial_agg_vals[agg_col_idx] = partial_bin_val;
1677  }
1678  }
1679  if (kAVG == agg_info.agg_kind) {
1680  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1681  ++agg_col_idx;
1682  partial_bin_val = partial_agg_vals[agg_col_idx] =
1683  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1684  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1685  }
1686  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1687  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1688  CHECK(agg_info.is_agg);
1689  discard_partial_result = false;
1690  }
1691  }
1692  row_ptr += row_size;
1693  if (discard_partial_result) {
1694  continue;
1695  }
1696  discard_row = false;
1697  for (size_t target_idx = 0, agg_col_idx = 0;
1698  target_idx < targets.size() && agg_col_idx < agg_col_count;
1699  ++target_idx, ++agg_col_idx) {
1700  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1701  const auto& agg_info = targets[target_idx];
1702  const bool float_argument_input = takes_float_argument(agg_info);
1703  const auto chosen_bytes = float_argument_input
1704  ? sizeof(float)
1705  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1706  const auto& chosen_type = get_compact_type(agg_info);
1707  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1708  try {
1709  switch (agg_info.agg_kind) {
1710  case kCOUNT:
1711  case kCOUNT_IF:
1714  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1715  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1716  agg_init_vals[agg_col_idx],
1717  chosen_bytes,
1718  agg_info);
1719  break;
1720  case kAVG:
1721  // Ignore float argument compaction for count component for fear of its
1722  // overflow
1724  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1725  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1726  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1727  // fall thru
1728  case kSUM:
1729  case kSUM_IF:
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 (!(shared::is_any<kCOUNT, kCOUNT_IF>(agg_info.agg_kind) &&
1791  ret != agg_init_vals[agg_col_idx])) {
1792  agg_vals[agg_col_idx] = static_cast<int64_t>(ret);
1793  }
1794  break;
1795  }
1796  default:
1797  CHECK(false);
1798  }
1799  }
1800  if (kAVG == agg_info.agg_kind) {
1801  ++agg_col_idx;
1802  }
1803  } else {
1804  if (agg_info.agg_kind == kSAMPLE) {
1805  CHECK(!agg_info.sql_type.is_varlen())
1806  << "Interleaved bins reduction not supported for variable length "
1807  "arguments "
1808  "to SAMPLE";
1809  }
1810  if (agg_vals[agg_col_idx]) {
1811  if (agg_info.agg_kind == kSAMPLE) {
1812  continue;
1813  }
1814  CHECK_EQ(agg_vals[agg_col_idx], partial_bin_val);
1815  } else {
1816  agg_vals[agg_col_idx] = partial_bin_val;
1817  }
1818  }
1819  }
1820  }
1821  return discard_row;
1822 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:285
#define CHECK_GE(x, y)
Definition: Logger.h:306
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
size_t getColOnlyOffInBytes(const size_t col_idx) const
Definition: sqldefs.h:75
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:77
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:102
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:78
#define AGGREGATE_ONE_NULLABLE_COUNT(val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK(condition)
Definition: Logger.h:291
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
Definition: sqldefs.h:76
Definition: sqldefs.h:74
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:305
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:303
#define CHECK(condition)
Definition: Logger.h:291
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: