OmniSciDB  95562058bd
 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 704 of file ResultSet.cpp.

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

705  {
706  const size_t num_storage_entries = result_set_->query_mem_desc_.getEntryCount();
707  std::vector<int64_t> count_distinct_materialized_buffer(num_storage_entries);
708  const CountDistinctDescriptor count_distinct_descriptor =
709  result_set_->query_mem_desc_.getCountDistinctDescriptor(order_entry.tle_no - 1);
710  const size_t num_non_empty_entries = result_set_->permutation_.size();
711  const size_t worker_count = cpu_threads();
712  // TODO(tlm): Allow use of tbb after we determine how to easily encapsulate the choice
713  // between thread pool types
715  for (size_t i = 0,
716  start_entry = 0,
717  stride = (num_non_empty_entries + worker_count - 1) / worker_count;
718  i < worker_count && start_entry < num_non_empty_entries;
719  ++i, start_entry += stride) {
720  const auto end_entry = std::min(start_entry + stride, num_non_empty_entries);
721  thread_pool.spawn(
722  [this](const size_t start,
723  const size_t end,
724  const Analyzer::OrderEntry& order_entry,
725  const CountDistinctDescriptor& count_distinct_descriptor,
726  std::vector<int64_t>& count_distinct_materialized_buffer) {
727  for (size_t i = start; i < end; ++i) {
728  const uint32_t permuted_idx = result_set_->permutation_[i];
729  const auto storage_lookup_result = result_set_->findStorage(permuted_idx);
730  const auto storage = storage_lookup_result.storage_ptr;
731  const auto off = storage_lookup_result.fixedup_entry_idx;
732  const auto value = buffer_itr_.getColumnInternal(
733  storage->buff_, off, order_entry.tle_no - 1, storage_lookup_result);
734  count_distinct_materialized_buffer[permuted_idx] =
735  count_distinct_set_size(value.i1, count_distinct_descriptor);
736  }
737  },
738  start_entry,
739  end_entry,
740  std::cref(order_entry),
741  std::cref(count_distinct_descriptor),
742  std::ref(count_distinct_materialized_buffer));
743  }
744  thread_pool.join();
745  return count_distinct_materialized_buffer;
746 }
const BufferIteratorType buffer_itr_
Definition: ResultSet.h:770
int tle_no
Definition: Analyzer.h:1418
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 spawn(Function &&f, Args &&...args)
Definition: threadpool.h:33
Definition: Analyzer.h:1413
int cpu_threads()
Definition: thread_count.h:24

+ Here is the call graph for this function:

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

Definition at line 693 of file ResultSet.cpp.

References is_distinct_target().

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

693  {
694  for (const auto& order_entry : order_entries_) {
695  if (is_distinct_target(result_set_->targets_[order_entry.tle_no - 1])) {
697  materializeCountDistinctColumn(order_entry));
698  }
699  }
700 }
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:704
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 749 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.

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