Turi Create  4.0
sort_comparator.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_QUERY_EVAL_SORT_COMPARATOR_HPP
7 #define TURI_QUERY_EVAL_SORT_COMPARATOR_HPP
8 
9 #include <core/data/flexible_type/flexible_type.hpp>
10 
11 namespace turi {
12 
13 namespace query_eval {
14 
15 /**
16  * \ingroup sframe_query_engine
17  * \addtogroup Algorithms Algorithms
18  * \{
19  */
20 
21 /**
22  * \internal
23  * Comparator that compares two flex_list value with given ascending/descending
24  * order. Order value "true" means ascending, "false" means descending
25  * it compares all values in the two flex_list types
26  **/
28 {
30  less_than_full_function(const std::vector<bool>& sort_orders):
31  m_sort_orders(sort_orders) {}
32 
33  inline bool operator() (const flexible_type& v1, const flexible_type& v2) const
34  {
37 
38  const flex_list& v1_v = v1.get<flex_list>();
39  const flex_list& v2_v = v2.get<flex_list>();
40  return compare(v1_v, v2_v);
41  }
42 
43 
44  inline bool operator() (const std::vector<flexible_type>& v1, const std::vector<flexible_type>& v2) const {
45  return compare(v1, v2);
46  }
47 
48  inline bool operator() (const std::pair<std::vector<flexible_type>, std::string>& v1,
49  const std::pair<std::vector<flexible_type>, std::string>& v2) const {
50  return compare(v1.first, v2.first);
51  }
52 
53  inline bool compare(const std::vector<flexible_type>& v1, const std::vector<flexible_type>& v2) const {
54  DASSERT_TRUE(v1.size() == v2.size());
55  DASSERT_TRUE(v1.size() == m_sort_orders.size());
56 
57  for(size_t i = 0; i < m_sort_orders.size(); i++) {
58  bool ascending = m_sort_orders[i];
59 
60  if (v1[i] == FLEX_UNDEFINED) {
61  if (v2[i] == FLEX_UNDEFINED) {
62  continue; // equal
63  } else {
64  return ascending;
65  }
66  }
67 
68  if (v2[i] == FLEX_UNDEFINED) {
69  return !ascending;
70  }
71 
72  if (v1[i] < v2[i]) return ascending;
73  if (v1[i] > v2[i]) return !ascending;
74  }
75 
76  return false;
77  }
78  std::vector<bool> m_sort_orders;
79 };
80 
81 
82 /**
83  * Comparator that compares two flex_list value with given ascending/descending
84  * order and given sort columns.
85  * This is different from above in that it is only comparing part of the columns
86  * in the value, not all the values
87  * Order value "true" means ascending, "false" means descending
88  **/
90 {
91  less_than_partial_function(const std::vector<size_t>& sort_columns,
92  const std::vector<bool>& sort_orders)
93  : m_sort_columns(sort_columns), m_sort_orders(sort_orders)
94  {
95  DASSERT_TRUE(sort_orders.size() == sort_columns.size());
96  }
97 
98  inline bool operator() (const std::vector<flexible_type>& v1, const std::vector<flexible_type>& v2)
99  {
100  DASSERT_TRUE(v1.size() == v2.size());
101 
102  size_t i = 0;
103  for(auto column_idx: m_sort_columns) {
104  DASSERT_TRUE(v1.size() > column_idx);
105  bool ascending = m_sort_orders[i++];
106 
107  if (v1[column_idx] == FLEX_UNDEFINED) {
108  if (v2[column_idx] == FLEX_UNDEFINED) continue;
109  return ascending;
110  }
111 
112  if (v2[column_idx] == FLEX_UNDEFINED) {
113  return !ascending;
114  }
115 
116  if (v1[column_idx] < v2[column_idx]) return ascending;
117  if (v1[column_idx] > v2[column_idx]) return !ascending;
118  }
119 
120  return false;
121  }
122  std::vector<size_t> m_sort_columns;
123  std::vector<bool> m_sort_orders;
124 };
125 
126 /// \}
127 } // end query_eval
128 } // end turicreate
129 
130 #endif
const T & get() const
flex_type_enum get_type() const
static flexible_type FLEX_UNDEFINED
std::vector< flexible_type > flex_list
#define DASSERT_TRUE(cond)
Definition: assertions.hpp:364