OmniSciDB  16c4e035a1
 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
 
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 98 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 55 of file ResultSetStorage.cpp.

59  : targets_(targets)
60  , query_mem_desc_(query_mem_desc)
61  , buff_(buff)
62  , 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 69 of file ResultSetStorage.cpp.

References CHECK, and count_distinct_sets_mapping_.

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

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

2173  {
2174  // Note that table function result sets should never use this path as the row count
2175  // can be known statically (as the output buffers do not contain empty entries)
2178 
2179  if (!query_mem_desc_.getEntryCount()) {
2180  return 0;
2181  }
2182 
2184  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2185  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2186  });
2187  } else {
2188  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2189  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2190  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2191  });
2192  }
2193 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
#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:211
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 507 of file ResultSetReduction.cpp.

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

Referenced by reduceEntriesNoCollisionsColWise().

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

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

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

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

1145  {
1146  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1147  const auto key_count = query_mem_desc_.getGroupbyColCount();
1148  CHECK_EQ(slot_count + key_count, entry.size());
1149  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1151  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1152  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1153  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1154  for (size_t i = 0; i < key_count; ++i) {
1155  this_buff[key_off + i] = entry[i];
1156  }
1157  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1158  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1159  this_buff[first_slot_off + i] = entry[key_count + i];
1160  }
1161 }
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:219
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:211
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

size_t ResultSetStorage::getEntryCount ( ) const
inline

Definition at line 115 of file ResultSetStorage.h.

References QueryMemoryDescriptor::getEntryCount(), and query_mem_desc_.

115 { 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 65 of file ResultSetStorage.cpp.

References buff_.

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

65  {
66  return buff_;
67 }

+ Here is the caller graph for this function:

const VarlenOutputInfo* ResultSetStorage::getVarlenOutputInfo ( ) const
inlineprivate

Definition at line 224 of file ResultSetStorage.h.

References varlen_output_info_.

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

Definition at line 1237 of file ResultSetReduction.cpp.

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

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

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

Definition at line 1217 of file ResultSetReduction.cpp.

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

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

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

Definition at line 1163 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(), i, query_mem_desc_, and target_init_vals_.

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

2055  {
2058  return false;
2059  }
2061  return isEmptyEntryColumnar(entry_idx, buff);
2062  }
2067  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2068  target_init_vals_.size());
2069  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2070  const auto target_slot_off = result_set::get_byteoff_of_slot(
2072  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2076  } else {
2077  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2079  case 4:
2082  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2083  case 8:
2084  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2085  default:
2086  CHECK(false);
2087  return true;
2088  }
2089  }
2090 }
#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:224
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:221
#define CHECK(condition)
Definition: Logger.h:211
#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 2195 of file ResultSetIteration.cpp.

2195  {
2196  return isEmptyEntry(entry_idx, buff_);
2197 }
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 2096 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().

2097  {
2101  return false;
2102  }
2104  // For table functions the entry count should always be set to the actual output size
2105  // (i.e. there are not empty entries), so just assume value is non-empty
2106  CHECK_LT(entry_idx, getEntryCount());
2107  return false;
2108  }
2113  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2114  target_init_vals_.size());
2115  const auto col_buff = advance_col_buff_to_slot(
2117  const auto entry_buff =
2118  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2120  return read_int_from_buff(entry_buff,
2124  } else {
2125  // it's enough to find the first group key which is empty
2127  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2128  } else {
2130  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2131  switch (query_mem_desc_.groupColWidth(0)) {
2132  case 8:
2133  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2134  case 4:
2135  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2136  case 2:
2137  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2138  case 1:
2139  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2140  default:
2141  CHECK(false);
2142  }
2143  }
2144  return false;
2145  }
2146  return false;
2147 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
std::vector< int64_t > target_init_vals_
#define CHECK_GE(x, y)
Definition: Logger.h:224
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
const int8_t * col_buff
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:221
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:211
#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 75 of file ResultSetStorage.cpp.

References count_distinct_sets_mapping_.

75  {
76  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
77  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
78  // remote ptr that do not not exists. Return 0 if no pointer found
79  if (it == count_distinct_sets_mapping_.end()) {
80  return int64_t(0);
81  }
82  return it->second;
83 }
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 942 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().

943  {
945  CHECK_GT(new_entry_count, query_mem_desc_.getEntryCount());
946  auto new_buff_i64 = reinterpret_cast<int64_t*>(new_buff);
947  const auto key_count = query_mem_desc_.getGroupbyColCount();
950  const auto src_buff = reinterpret_cast<const int64_t*>(buff_);
951  const auto row_qw_count = get_row_qw_count(query_mem_desc_);
952  const auto key_byte_width = query_mem_desc_.getEffectiveKeyWidth();
953 
955  const size_t thread_count = cpu_threads();
956  std::vector<std::future<void>> move_threads;
957 
958  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
959  const auto thread_entry_count =
960  (query_mem_desc_.getEntryCount() + thread_count - 1) / thread_count;
961  const auto start_index = thread_idx * thread_entry_count;
962  const auto end_index =
963  std::min(start_index + thread_entry_count, query_mem_desc_.getEntryCount());
964  move_threads.emplace_back(std::async(
966  [this,
967  src_buff,
968  new_buff_i64,
969  new_entry_count,
970  start_index,
971  end_index,
972  key_count,
973  row_qw_count,
974  key_byte_width] {
975  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
976  moveOneEntryToBuffer<KeyType>(entry_idx,
977  new_buff_i64,
978  new_entry_count,
979  key_count,
980  row_qw_count,
981  src_buff,
982  key_byte_width);
983  }
984  }));
985  }
986  for (auto& move_thread : move_threads) {
987  move_thread.wait();
988  }
989  for (auto& move_thread : move_threads) {
990  move_thread.get();
991  }
992  } else {
993  for (size_t entry_idx = 0; entry_idx < query_mem_desc_.getEntryCount(); ++entry_idx) {
994  moveOneEntryToBuffer<KeyType>(entry_idx,
995  new_buff_i64,
996  new_entry_count,
997  key_count,
998  row_qw_count,
999  src_buff,
1000  key_byte_width);
1001  }
1002  }
1003 }
size_t getEffectiveKeyWidth() const
#define CHECK_GT(x, y)
Definition: Logger.h:223
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:211
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
int cpu_threads()
Definition: thread_count.h:24
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 1006 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_.

1012  {
1013  const auto key_off =
1015  ? key_offset_colwise(entry_index, 0, query_mem_desc_.getEntryCount())
1016  : row_qw_count * entry_index;
1017  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
1018  if (*key_ptr == get_empty_key<KeyType>()) {
1019  return;
1020  }
1021  int64_t* new_entries_ptr{nullptr};
1023  const auto key =
1024  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
1025  new_entries_ptr =
1026  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
1027  } else {
1028  new_entries_ptr = get_group_value(new_buff_i64,
1029  new_entry_count,
1030  &src_buff[key_off],
1031  key_count,
1032  key_byte_width,
1033  row_qw_count);
1034  }
1035  CHECK(new_entries_ptr);
1036  fill_slots(new_entries_ptr,
1037  new_entry_count,
1038  src_buff,
1039  entry_index,
1041  query_mem_desc_);
1042 }
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:211
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

Definition at line 206 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, i, 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().

208  {
209  auto entry_count = query_mem_desc_.getEntryCount();
210  CHECK_GT(entry_count, size_t(0));
218  }
219  const auto that_entry_count = that.query_mem_desc_.getEntryCount();
222  CHECK_GE(entry_count, that_entry_count);
223  break;
224  default:
225  CHECK_EQ(entry_count, that_entry_count);
226  }
227  auto this_buff = buff_;
228  CHECK(this_buff);
229  auto that_buff = that.buff_;
230  CHECK(that_buff);
233  if (!serialized_varlen_buffer.empty()) {
234  throw std::runtime_error(
235  "Projection of variable length targets with baseline hash group by is not yet "
236  "supported in Distributed mode");
237  }
238  if (use_multithreaded_reduction(that_entry_count)) {
239  const size_t thread_count = cpu_threads();
240  std::vector<std::future<void>> reduction_threads;
241  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
242  const auto thread_entry_count =
243  (that_entry_count + thread_count - 1) / thread_count;
244  const auto start_index = thread_idx * thread_entry_count;
245  const auto end_index =
246  std::min(start_index + thread_entry_count, that_entry_count);
247  reduction_threads.emplace_back(std::async(
249  [this,
250  this_buff,
251  that_buff,
252  start_index,
253  end_index,
254  that_entry_count,
255  &reduction_code,
256  &that] {
257  if (reduction_code.ir_reduce_loop) {
258  run_reduction_code(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(reduction_code,
284  this_buff,
285  that_buff,
286  0,
287  that_entry_count,
288  that_entry_count,
290  &that.query_mem_desc_,
291  nullptr);
292  } else {
293  for (size_t i = 0; i < that_entry_count; ++i) {
294  reduceOneEntryBaseline(this_buff, that_buff, i, that_entry_count, that);
295  }
296  }
297  }
298  return;
299  }
300  auto executor = query_mem_desc_.getExecutor();
301  if (!executor) {
303  }
304  auto executor_id = executor->getExecutorId();
305  if (use_multithreaded_reduction(entry_count)) {
306  const size_t thread_count = cpu_threads();
307  std::vector<std::future<void>> reduction_threads;
308  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
309  const auto thread_entry_count = (entry_count + thread_count - 1) / thread_count;
310  const auto start_index = thread_idx * thread_entry_count;
311  const auto end_index = std::min(start_index + thread_entry_count, entry_count);
313  reduction_threads.emplace_back(std::async(std::launch::async,
314  [this,
315  this_buff,
316  that_buff,
317  start_index,
318  end_index,
319  &that,
320  &serialized_varlen_buffer,
321  &executor_id] {
323  this_buff,
324  that_buff,
325  that,
326  start_index,
327  end_index,
328  serialized_varlen_buffer,
329  executor_id);
330  }));
331  } else {
332  reduction_threads.emplace_back(std::async(std::launch::async,
333  [this,
334  this_buff,
335  that_buff,
336  start_index,
337  end_index,
338  that_entry_count,
339  &reduction_code,
340  &that,
341  &serialized_varlen_buffer] {
342  CHECK(reduction_code.ir_reduce_loop);
344  reduction_code,
345  this_buff,
346  that_buff,
347  start_index,
348  end_index,
349  that_entry_count,
351  &that.query_mem_desc_,
352  &serialized_varlen_buffer);
353  }));
354  }
355  }
356  for (auto& reduction_thread : reduction_threads) {
357  reduction_thread.wait();
358  }
359  for (auto& reduction_thread : reduction_threads) {
360  reduction_thread.get();
361  }
362  } else {
365  that_buff,
366  that,
367  0,
369  serialized_varlen_buffer,
370  executor_id);
371  } else {
372  CHECK(reduction_code.ir_reduce_loop);
373  run_reduction_code(reduction_code,
374  this_buff,
375  that_buff,
376  0,
377  entry_count,
378  that_entry_count,
380  &that.query_mem_desc_,
381  &serialized_varlen_buffer);
382  }
383  }
384 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
void run_reduction_code(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)
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:224
#define CHECK_GT(x, y)
Definition: Logger.h:223
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:179
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:211
int cpu_threads()
Definition: thread_count.h:24
const Executor * getExecutor() const
QueryMemoryDescriptor query_mem_desc_
static const ExecutorId UNITARY_EXECUTOR_ID
Definition: Execute.h:377

+ 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 408 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.

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

835  {
837  check_watchdog_with_seed(that_entry_idx);
838  }
839  const auto key_count = query_mem_desc_.getGroupbyColCount();
844  const auto key_off =
846  if (isEmptyEntry(that_entry_idx, that_buff)) {
847  return;
848  }
849  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
850  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
851  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
852  auto [this_entry_slots, empty_entry] = get_group_value_columnar_reduction(
853  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
854  CHECK(this_entry_slots);
855  if (empty_entry) {
856  fill_slots(this_entry_slots,
858  that_buff_i64,
859  that_entry_idx,
860  that_entry_count,
862  return;
863  }
865  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
866 }
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:77
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:211
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 868 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().

872  {
874  const auto key_count = query_mem_desc_.getGroupbyColCount();
875  size_t j = 0;
876  size_t init_agg_val_idx = 0;
877  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
878  ++target_logical_idx) {
879  const auto& target_info = targets_[target_logical_idx];
880  const auto that_slot_off = slot_offset_colwise(
881  that_entry_idx, init_agg_val_idx, key_count, that_entry_count);
882  const auto this_slot_off = init_agg_val_idx * query_mem_desc_.getEntryCount();
883  reduceOneSlotBaseline(this_entry_slots,
884  this_slot_off,
885  that_buff,
886  that_entry_count,
887  that_slot_off,
888  target_info,
889  target_logical_idx,
890  j,
891  init_agg_val_idx,
892  that);
894  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
895  } else {
896  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
897  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
898  }
899  }
900  j = advance_slot(j, target_info, false);
901  }
902 }
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:211
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 1457 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().

1468  {
1470  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1471  return;
1472  }
1473  }
1474  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1475  const bool float_argument_input = takes_float_argument(target_info);
1476  const auto chosen_bytes = result_set::get_width_for_slot(
1477  target_slot_idx, float_argument_input, query_mem_desc_);
1478  int64_t init_val = target_init_vals_[init_agg_val_idx]; // skip_val for nullable types
1479 
1480  if (target_info.is_agg && target_info.agg_kind == kSINGLE_VALUE) {
1482  this_ptr1, target_info, target_logical_idx, init_agg_val_idx, that_ptr1);
1483  } else if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1484  switch (target_info.agg_kind) {
1485  case kCOUNT:
1486  case kAPPROX_COUNT_DISTINCT: {
1487  if (is_distinct_target(target_info)) {
1488  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1489  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1490  break;
1491  }
1492  CHECK_EQ(int64_t(0), init_val);
1493  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1494  break;
1495  }
1496  case kAVG: {
1497  // Ignore float argument compaction for count component for fear of its overflow
1498  AGGREGATE_ONE_COUNT(this_ptr2,
1499  that_ptr2,
1500  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1501  }
1502  // fall thru
1503  case kSUM: {
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:219
std::string toString(const ExtArgumentType &sig_type)
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:51
#define LOG(tag)
Definition: Logger.h:205
bool is_varlen() const
Definition: sqltypes.h:545
#define UNREACHABLE()
Definition: Logger.h:255
void reduceOneApproxQuantileSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:157
Definition: sqldefs.h:73
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:49
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:75
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:153
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
SQLAgg agg_kind
Definition: TargetInfo.h:50
#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:221
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:76
#define CHECK(condition)
Definition: Logger.h:211
bool is_geometry() const
Definition: sqltypes.h:531
#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:519
Definition: sqldefs.h:74
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:861
Definition: sqldefs.h:72
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 904 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().

913  {
915  int8_t* this_ptr2{nullptr};
916  const int8_t* that_ptr2{nullptr};
917  if (target_info.is_agg &&
918  (target_info.agg_kind == kAVG ||
919  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
920  const auto this_count_off = query_mem_desc_.getEntryCount();
921  const auto that_count_off = that_entry_count;
922  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
923  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
924  }
925  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
926  this_ptr2,
927  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
928  that_ptr2,
929  target_info,
930  target_logical_idx,
931  target_slot_idx,
932  init_agg_val_idx,
933  that,
934  target_slot_idx, // dummy, for now
935  {});
936 }
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:51
bool is_varlen() const
Definition: sqltypes.h:545
bool is_agg
Definition: TargetInfo.h:49
SQLAgg agg_kind
Definition: TargetInfo.h:50
#define CHECK(condition)
Definition: Logger.h:211
Definition: sqldefs.h:72
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 1409 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().

1413  {
1414  const bool float_argument_input = takes_float_argument(target_info);
1415  const auto chosen_bytes = result_set::get_width_for_slot(
1416  target_slot_idx, float_argument_input, query_mem_desc_);
1417  auto init_val = target_init_vals_[init_agg_val_idx];
1418 
1419  auto reduce = [&](auto const& size_tag) {
1420  using CastTarget = std::decay_t<decltype(size_tag)>;
1421  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1422  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1423  if (rhs_proj_col == init_val) {
1424  // ignore
1425  } else if (lhs_proj_col == init_val) {
1426  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1427  } else if (lhs_proj_col != rhs_proj_col) {
1428  throw std::runtime_error("Multiple distinct values encountered");
1429  }
1430  };
1431 
1432  switch (chosen_bytes) {
1433  case 1: {
1435  reduce(int8_t());
1436  break;
1437  }
1438  case 2: {
1440  reduce(int16_t());
1441  break;
1442  }
1443  case 4: {
1444  reduce(int32_t());
1445  break;
1446  }
1447  case 8: {
1448  CHECK(!target_info.sql_type.is_varlen());
1449  reduce(int64_t());
1450  break;
1451  }
1452  default:
1453  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1454  }
1455 }
std::vector< int64_t > target_init_vals_
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:51
#define LOG(tag)
Definition: Logger.h:205
bool is_varlen() const
Definition: sqltypes.h:545
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:157
void reduce(const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code) const
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:211
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, kMAX, kMIN, kSAMPLE, kSUM, 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 && (agg_info.agg_kind == kCOUNT ||
1671  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1672  partial_bin_val = count_distinct_set_size(
1673  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1674  if (replace_bitmap_ptr_with_bitmap_sz) {
1675  partial_agg_vals[agg_col_idx] = partial_bin_val;
1676  }
1677  }
1678  if (kAVG == agg_info.agg_kind) {
1679  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1680  ++agg_col_idx;
1681  partial_bin_val = partial_agg_vals[agg_col_idx] =
1682  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1683  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1684  }
1685  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1686  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1687  CHECK(agg_info.is_agg);
1688  discard_partial_result = false;
1689  }
1690  }
1691  row_ptr += row_size;
1692  if (discard_partial_result) {
1693  continue;
1694  }
1695  discard_row = false;
1696  for (size_t target_idx = 0, agg_col_idx = 0;
1697  target_idx < targets.size() && agg_col_idx < agg_col_count;
1698  ++target_idx, ++agg_col_idx) {
1699  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1700  const auto& agg_info = targets[target_idx];
1701  const bool float_argument_input = takes_float_argument(agg_info);
1702  const auto chosen_bytes = float_argument_input
1703  ? sizeof(float)
1704  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1705  const auto& chosen_type = get_compact_type(agg_info);
1706  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1707  try {
1708  switch (agg_info.agg_kind) {
1709  case kCOUNT:
1712  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1713  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1714  agg_init_vals[agg_col_idx],
1715  chosen_bytes,
1716  agg_info);
1717  break;
1718  case kAVG:
1719  // Ignore float argument compaction for count component for fear of its
1720  // overflow
1722  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1723  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1724  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1725  // fall thru
1726  case kSUM:
1728  sum,
1729  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1730  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1731  agg_init_vals[agg_col_idx],
1732  chosen_bytes,
1733  agg_info);
1734  break;
1735  case kMIN:
1736  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1738  min,
1739  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1740  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1741  agg_init_vals[agg_col_idx],
1742  chosen_bytes,
1743  agg_info);
1744  } else {
1746  min,
1747  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1748  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1749  agg_init_vals[agg_col_idx],
1750  chosen_bytes,
1751  agg_info);
1752  }
1753  break;
1754  case kMAX:
1755  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1757  max,
1758  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1759  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1760  agg_init_vals[agg_col_idx],
1761  chosen_bytes,
1762  agg_info);
1763  } else {
1765  max,
1766  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1767  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1768  agg_init_vals[agg_col_idx],
1769  chosen_bytes,
1770  agg_info);
1771  }
1772  break;
1773  default:
1774  CHECK(false);
1775  break;
1776  }
1777  } catch (std::runtime_error& e) {
1778  // TODO(miyu): handle the case where chosen_bytes < 8
1779  LOG(ERROR) << e.what();
1780  }
1781  if (chosen_type.is_integer() || chosen_type.is_decimal()) {
1782  switch (chosen_bytes) {
1783  case 8:
1784  break;
1785  case 4: {
1786  int32_t ret = *reinterpret_cast<const int32_t*>(&agg_vals[agg_col_idx]);
1787  if (!(agg_info.agg_kind == kCOUNT && ret != agg_init_vals[agg_col_idx])) {
1788  agg_vals[agg_col_idx] = static_cast<int64_t>(ret);
1789  }
1790  break;
1791  }
1792  default:
1793  CHECK(false);
1794  }
1795  }
1796  if (kAVG == agg_info.agg_kind) {
1797  ++agg_col_idx;
1798  }
1799  } else {
1800  if (agg_info.agg_kind == kSAMPLE) {
1801  CHECK(!agg_info.sql_type.is_varlen())
1802  << "Interleaved bins reduction not supported for variable length "
1803  "arguments "
1804  "to SAMPLE";
1805  }
1806  if (agg_vals[agg_col_idx]) {
1807  if (agg_info.agg_kind == kSAMPLE) {
1808  continue;
1809  }
1810  CHECK_EQ(agg_vals[agg_col_idx], partial_bin_val);
1811  } else {
1812  agg_vals[agg_col_idx] = partial_bin_val;
1813  }
1814  }
1815  }
1816  }
1817  return discard_row;
1818 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
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:205
#define CHECK_GE(x, y)
Definition: Logger.h:224
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:157
size_t getColOnlyOffInBytes(const size_t col_idx) const
Definition: sqldefs.h:73
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:75
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:153
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:76
#define AGGREGATE_ONE_NULLABLE_COUNT(val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK(condition)
Definition: Logger.h:211
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
Definition: sqldefs.h:74
Definition: sqldefs.h:72
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 544 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(), i, isEmptyEntry(), kSAMPLE, query_mem_desc_, row_ptr_rowwise(), and targets_.

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

References query_mem_desc_, and QueryMemoryDescriptor::setEntryCount().

129  {
130  query_mem_desc_.setEntryCount(new_entry_count);
131  }
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 251 of file ResultSetStorage.h.

friend class ResultSetManager
friend

Definition at line 252 of file ResultSetStorage.h.

Member Data Documentation

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 239 of file ResultSetStorage.h.

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

Definition at line 246 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 249 of file ResultSetStorage.h.

Referenced by getVarlenOutputInfo().


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