OmniSciDB  06b3bd477c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE > Struct Template Reference
+ Collaboration diagram for ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >:

Public Types

using BufferIteratorType = BUFFER_ITERATOR_TYPE
 

Public Member Functions

 ResultSetComparator (const std::list< Analyzer::OrderEntry > &order_entries, const bool use_heap, const ResultSet *result_set)
 
void materializeCountDistinctColumns ()
 
std::vector< int64_t > materializeCountDistinctColumn (const Analyzer::OrderEntry &order_entry) const
 
bool operator() (const uint32_t lhs, const uint32_t rhs) const
 

Public Attributes

const std::list
< Analyzer::OrderEntry
order_entries_
 
const bool use_heap_
 
const ResultSetresult_set_
 
const BufferIteratorType buffer_itr_
 
std::vector< std::vector
< int64_t > > 
count_distinct_materialized_buffers_
 

Detailed Description

template<typename BUFFER_ITERATOR_TYPE>
struct ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >

Definition at line 746 of file ResultSet.h.

Member Typedef Documentation

template<typename BUFFER_ITERATOR_TYPE >
using ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::BufferIteratorType = BUFFER_ITERATOR_TYPE

Definition at line 747 of file ResultSet.h.

Constructor & Destructor Documentation

template<typename BUFFER_ITERATOR_TYPE >
ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::ResultSetComparator ( const std::list< Analyzer::OrderEntry > &  order_entries,
const bool  use_heap,
const ResultSet result_set 
)
inline

Definition at line 749 of file ResultSet.h.

References ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::materializeCountDistinctColumns().

752  : order_entries_(order_entries)
753  , use_heap_(use_heap)
754  , result_set_(result_set)
755  , buffer_itr_(result_set) {
757  }
const std::list< Analyzer::OrderEntry > order_entries_
Definition: ResultSet.h:767
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:770
const ResultSet * result_set_
Definition: ResultSet.h:769

+ Here is the call graph for this function:

Member Function Documentation

template<typename BUFFER_ITERATOR_TYPE >
std::vector< int64_t > ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::materializeCountDistinctColumn ( const Analyzer::OrderEntry order_entry) const

Definition at line 697 of file ResultSet.cpp.

References threadpool::FuturesThreadPoolBase< T >::append(), count_distinct_set_size(), cpu_threads(), threadpool::FuturesThreadPool< T, ENABLE >::join(), and Analyzer::OrderEntry::tle_no.

698  {
699  const size_t num_storage_entries = result_set_->query_mem_desc_.getEntryCount();
700  std::vector<int64_t> count_distinct_materialized_buffer(num_storage_entries);
701  const CountDistinctDescriptor count_distinct_descriptor =
702  result_set_->query_mem_desc_.getCountDistinctDescriptor(order_entry.tle_no - 1);
703  const size_t num_non_empty_entries = result_set_->permutation_.size();
704  const size_t worker_count = cpu_threads();
705  // TODO(tlm): Allow use of tbb after we determine how to easily encapsulate the choice
706  // between thread pool types
708  for (size_t i = 0,
709  start_entry = 0,
710  stride = (num_non_empty_entries + worker_count - 1) / worker_count;
711  i < worker_count && start_entry < num_non_empty_entries;
712  ++i, start_entry += stride) {
713  const auto end_entry = std::min(start_entry + stride, num_non_empty_entries);
714  thread_pool.append(
715  [this](const size_t start,
716  const size_t end,
717  const Analyzer::OrderEntry& order_entry,
718  const CountDistinctDescriptor& count_distinct_descriptor,
719  std::vector<int64_t>& count_distinct_materialized_buffer) {
720  for (size_t i = start; i < end; ++i) {
721  const uint32_t permuted_idx = result_set_->permutation_[i];
722  const auto storage_lookup_result = result_set_->findStorage(permuted_idx);
723  const auto storage = storage_lookup_result.storage_ptr;
724  const auto off = storage_lookup_result.fixedup_entry_idx;
725  const auto value = buffer_itr_.getColumnInternal(
726  storage->buff_, off, order_entry.tle_no - 1, storage_lookup_result);
727  count_distinct_materialized_buffer[permuted_idx] =
728  count_distinct_set_size(value.i1, count_distinct_descriptor);
729  }
730  },
731  start_entry,
732  end_entry,
733  std::cref(order_entry),
734  std::cref(count_distinct_descriptor),
735  std::ref(count_distinct_materialized_buffer));
736  }
737  thread_pool.join();
738  return count_distinct_materialized_buffer;
739 }
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:770
int tle_no
Definition: Analyzer.h:1419
int64_t count_distinct_set_size(const int64_t set_handle, const CountDistinctDescriptor &count_distinct_desc)
Definition: CountDistinct.h:75
const ResultSet * result_set_
Definition: ResultSet.h:769
void append(Function &&f, Args &&...args)
Definition: threadpool.h:33
Definition: Analyzer.h:1414
int cpu_threads()
Definition: thread_count.h:25

+ Here is the call graph for this function:

template<typename BUFFER_ITERATOR_TYPE >
void ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::materializeCountDistinctColumns ( )

Definition at line 686 of file ResultSet.cpp.

References is_distinct_target().

Referenced by ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::ResultSetComparator().

686  {
687  for (const auto& order_entry : order_entries_) {
688  if (is_distinct_target(result_set_->targets_[order_entry.tle_no - 1])) {
690  materializeCountDistinctColumn(order_entry));
691  }
692  }
693 }
const std::list< Analyzer::OrderEntry > order_entries_
Definition: ResultSet.h:767
std::vector< int64_t > materializeCountDistinctColumn(const Analyzer::OrderEntry &order_entry) const
Definition: ResultSet.cpp:697
const ResultSet * result_set_
Definition: ResultSet.h:769
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:129
std::vector< std::vector< int64_t > > count_distinct_materialized_buffers_
Definition: ResultSet.h:771

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<typename BUFFER_ITERATOR_TYPE >
bool ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::operator() ( const uint32_t  lhs,
const uint32_t  rhs 
) const

Definition at line 742 of file ResultSet.cpp.

References CHECK(), CHECK_EQ, CHECK_GE, CHECK_LT, get_compact_type(), is_distinct_target(), kENCODING_DICT, kFLOAT, LIKELY, pair_to_double(), takes_float_argument(), and UNLIKELY.

744  {
745  // NB: The compare function must define a strict weak ordering, otherwise
746  // std::sort will trigger a segmentation fault (or corrupt memory).
747  const auto lhs_storage_lookup_result = result_set_->findStorage(lhs);
748  const auto rhs_storage_lookup_result = result_set_->findStorage(rhs);
749  const auto lhs_storage = lhs_storage_lookup_result.storage_ptr;
750  const auto rhs_storage = rhs_storage_lookup_result.storage_ptr;
751  const auto fixedup_lhs = lhs_storage_lookup_result.fixedup_entry_idx;
752  const auto fixedup_rhs = rhs_storage_lookup_result.fixedup_entry_idx;
753  size_t materialized_count_distinct_buffer_idx{0};
754 
755  for (const auto& order_entry : order_entries_) {
756  CHECK_GE(order_entry.tle_no, 1);
757  const auto& agg_info = result_set_->targets_[order_entry.tle_no - 1];
758  const auto entry_ti = get_compact_type(agg_info);
759  bool float_argument_input = takes_float_argument(agg_info);
760  // Need to determine if the float value has been stored as float
761  // or if it has been compacted to a different (often larger 8 bytes)
762  // in distributed case the floats are actually 4 bytes
763  // TODO the above takes_float_argument() is widely used wonder if this problem
764  // exists elsewhere
765  if (entry_ti.get_type() == kFLOAT) {
766  const auto is_col_lazy =
767  !result_set_->lazy_fetch_info_.empty() &&
768  result_set_->lazy_fetch_info_[order_entry.tle_no - 1].is_lazily_fetched;
769  if (result_set_->query_mem_desc_.getPaddedSlotWidthBytes(order_entry.tle_no - 1) ==
770  sizeof(float)) {
771  float_argument_input =
772  result_set_->query_mem_desc_.didOutputColumnar() ? !is_col_lazy : true;
773  }
774  }
775 
776  const bool use_desc_cmp = use_heap_ ? !order_entry.is_desc : order_entry.is_desc;
777 
778  if (UNLIKELY(is_distinct_target(agg_info))) {
779  CHECK_LT(materialized_count_distinct_buffer_idx,
781  const auto& count_distinct_materialized_buffer =
782  count_distinct_materialized_buffers_[materialized_count_distinct_buffer_idx];
783  const auto lhs_sz = count_distinct_materialized_buffer[lhs];
784  const auto rhs_sz = count_distinct_materialized_buffer[rhs];
785  ++materialized_count_distinct_buffer_idx;
786  if (lhs_sz == rhs_sz) {
787  continue;
788  }
789  return use_desc_cmp ? lhs_sz > rhs_sz : lhs_sz < rhs_sz;
790  }
791 
792  const auto lhs_v = buffer_itr_.getColumnInternal(lhs_storage->buff_,
793  fixedup_lhs,
794  order_entry.tle_no - 1,
795  lhs_storage_lookup_result);
796  const auto rhs_v = buffer_itr_.getColumnInternal(rhs_storage->buff_,
797  fixedup_rhs,
798  order_entry.tle_no - 1,
799  rhs_storage_lookup_result);
800 
801  if (UNLIKELY(isNull(entry_ti, lhs_v, float_argument_input) &&
802  isNull(entry_ti, rhs_v, float_argument_input))) {
803  return false;
804  }
805  if (UNLIKELY(isNull(entry_ti, lhs_v, float_argument_input) &&
806  !isNull(entry_ti, rhs_v, float_argument_input))) {
807  return use_heap_ ? !order_entry.nulls_first : order_entry.nulls_first;
808  }
809  if (UNLIKELY(isNull(entry_ti, rhs_v, float_argument_input) &&
810  !isNull(entry_ti, lhs_v, float_argument_input))) {
811  return use_heap_ ? order_entry.nulls_first : !order_entry.nulls_first;
812  }
813 
814  if (LIKELY(lhs_v.isInt())) {
815  CHECK(rhs_v.isInt());
816  if (UNLIKELY(entry_ti.is_string() &&
817  entry_ti.get_compression() == kENCODING_DICT)) {
818  CHECK_EQ(4, entry_ti.get_logical_size());
819  const auto string_dict_proxy = result_set_->executor_->getStringDictionaryProxy(
820  entry_ti.get_comp_param(), result_set_->row_set_mem_owner_, false);
821  auto lhs_str = string_dict_proxy->getString(lhs_v.i1);
822  auto rhs_str = string_dict_proxy->getString(rhs_v.i1);
823  if (lhs_str == rhs_str) {
824  continue;
825  }
826  return use_desc_cmp ? lhs_str > rhs_str : lhs_str < rhs_str;
827  }
828 
829  if (lhs_v.i1 == rhs_v.i1) {
830  continue;
831  }
832  if (entry_ti.is_fp()) {
833  if (float_argument_input) {
834  const auto lhs_dval = *reinterpret_cast<const float*>(may_alias_ptr(&lhs_v.i1));
835  const auto rhs_dval = *reinterpret_cast<const float*>(may_alias_ptr(&rhs_v.i1));
836  return use_desc_cmp ? lhs_dval > rhs_dval : lhs_dval < rhs_dval;
837  } else {
838  const auto lhs_dval =
839  *reinterpret_cast<const double*>(may_alias_ptr(&lhs_v.i1));
840  const auto rhs_dval =
841  *reinterpret_cast<const double*>(may_alias_ptr(&rhs_v.i1));
842  return use_desc_cmp ? lhs_dval > rhs_dval : lhs_dval < rhs_dval;
843  }
844  }
845  return use_desc_cmp ? lhs_v.i1 > rhs_v.i1 : lhs_v.i1 < rhs_v.i1;
846  } else {
847  if (lhs_v.isPair()) {
848  CHECK(rhs_v.isPair());
849  const auto lhs =
850  pair_to_double({lhs_v.i1, lhs_v.i2}, entry_ti, float_argument_input);
851  const auto rhs =
852  pair_to_double({rhs_v.i1, rhs_v.i2}, entry_ti, float_argument_input);
853  if (lhs == rhs) {
854  continue;
855  }
856  return use_desc_cmp ? lhs > rhs : lhs < rhs;
857  } else {
858  CHECK(lhs_v.isStr() && rhs_v.isStr());
859  const auto lhs = lhs_v.strVal();
860  const auto rhs = rhs_v.strVal();
861  if (lhs == rhs) {
862  continue;
863  }
864  return use_desc_cmp ? lhs > rhs : lhs < rhs;
865  }
866  }
867  }
868  return false;
869 }
const std::list< Analyzer::OrderEntry > order_entries_
Definition: ResultSet.h:767
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:770
static bool isNull(const SQLTypeInfo &ti, const InternalTargetValue &val, const bool float_argument_input)
#define CHECK_GE(x, y)
Definition: Logger.h:210
double pair_to_double(const std::pair< int64_t, int64_t > &fp_pair, const SQLTypeInfo &ti, const bool float_argument_input)
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:133
const SQLTypeInfo get_compact_type(const TargetInfo &target)
CHECK(cgen_state)
const ResultSet * result_set_
Definition: ResultSet.h:769
#define LIKELY(x)
Definition: likely.h:19
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:129
#define UNLIKELY(x)
Definition: likely.h:20
#define CHECK_LT(x, y)
Definition: Logger.h:207
std::vector< std::vector< int64_t > > count_distinct_materialized_buffers_
Definition: ResultSet.h:771

+ Here is the call graph for this function:

Member Data Documentation

template<typename BUFFER_ITERATOR_TYPE >
const BufferIteratorType ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::buffer_itr_

Definition at line 770 of file ResultSet.h.

template<typename BUFFER_ITERATOR_TYPE >
std::vector<std::vector<int64_t> > ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::count_distinct_materialized_buffers_

Definition at line 771 of file ResultSet.h.

template<typename BUFFER_ITERATOR_TYPE >
const std::list<Analyzer::OrderEntry> ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::order_entries_

Definition at line 767 of file ResultSet.h.

template<typename BUFFER_ITERATOR_TYPE >
const ResultSet* ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::result_set_

Definition at line 769 of file ResultSet.h.

template<typename BUFFER_ITERATOR_TYPE >
const bool ResultSet::ResultSetComparator< BUFFER_ITERATOR_TYPE >::use_heap_

Definition at line 768 of file ResultSet.h.


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