Skip to content

Commit eaab112

Browse files
authored
Implement sort by view (#8)
1 parent c55f34a commit eaab112

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ These are the most useful operations.
66
- `.operator[](row_idx)` read data out as tuple of references
77
- `.get_column<col_idx>()` direct access to underlying std::vector column
88
- `.view<col_idx1, col_idx2, ...>(row_idx)` read subset of the fields out as a tuple of references
9+
- `.sort_by_view<col_idx1, col_idx2, ...>()` sort all columns in tandem based on a subset of columns
910

1011
Code Example (scratch.cpp)
1112
------------------------
@@ -86,6 +87,24 @@ int main(int argc, char *argv[])
8687
});
8788
std::cout << presidents << "\n";
8889

90+
// We can also sort by a view.
91+
std::cout << "Sorting by first name, last name." << "\n";
92+
presidents.sort_by_view<FIRST_NAME,LAST_NAME>();
93+
std::cout << presidents << "\n";
94+
95+
// We can also use a comparator when sorting by view.
96+
// In that case, the comparator should take a tuple of references.
97+
// For example, we can sort by difference in length of last and first name.
98+
std::cout << "Sorting by length of first name - length of last name." << "\n";
99+
presidents.sort_by_view<LAST_NAME, FIRST_NAME>([](auto view1, auto view2) {
100+
const auto& [lname_a, fname_a] = view1;
101+
const auto& [lname_b, fname_b] = view2;
102+
int view1_order = -int(lname_a.size()) + int(fname_a.size());
103+
int view2_order = -int(lname_b.size()) + int(fname_b.size());
104+
return view1_order < view2_order;
105+
});
106+
std::cout << presidents << "\n";
107+
89108
return 0;
90109
}
91110
```
@@ -164,6 +183,26 @@ soa {
164183
0, George, Washington
165184
}
166185

186+
Sorting by first name, last name.
187+
soa {
188+
3, Barack, Obama
189+
1, Bill, Clinton
190+
4, Donald, Trump
191+
2, George, Bush
192+
0, George, Washington
193+
5, Joseph, Biden
194+
}
195+
196+
Sorting by length of first name - length of last name.
197+
soa {
198+
0, George, Washington
199+
1, Bill, Clinton
200+
3, Barack, Obama
201+
4, Donald, Trump
202+
5, Joseph, Biden
203+
2, George, Bush
204+
}
205+
167206
```
168207
169208
Benchmark

scratch.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,23 @@ int main(int argc, char *argv[])
7373
});
7474
std::cout << presidents << "\n";
7575

76+
// We can also sort by a view.
77+
std::cout << "Sorting by first name, last name." << "\n";
78+
presidents.sort_by_view<FIRST_NAME,LAST_NAME>();
79+
std::cout << presidents << "\n";
80+
81+
// We can also use a comparator when sorting by view.
82+
// In that case, the comparator should take a tuple of references.
83+
// For example, we can sort by difference in length of last and first name.
84+
std::cout << "Sorting by length of first name - length of last name." << "\n";
85+
presidents.sort_by_view<LAST_NAME, FIRST_NAME>([](auto view1, auto view2) {
86+
const auto& [lname_a, fname_a] = view1;
87+
const auto& [lname_b, fname_b] = view2;
88+
int view1_order = -int(lname_a.size()) + int(fname_a.size());
89+
int view2_order = -int(lname_b.size()) + int(fname_b.size());
90+
return view1_order < view2_order;
91+
});
92+
std::cout << presidents << "\n";
93+
7694
return 0;
7795
}

vapid/soa.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,31 @@ namespace vapid {
214214
sort_by_field<col_idx>([](auto&& a, auto&& b) { return a < b; });
215215
}
216216

217+
template <size_t... I, typename C>
218+
void sort_by_view(C&& comparator) {
219+
reset_sort_reference();
220+
221+
auto comparator_wrapper = [=](size_t a, size_t b) {
222+
return comparator(view<I...>(a),
223+
view<I...>(b));
224+
};
225+
226+
std::stable_sort(sort_order_reference_.begin(),
227+
sort_order_reference_.end(),
228+
comparator_wrapper);
229+
230+
if (no_double_buffering_) {
231+
sort_order_analysis_.store_analysis(sort_order_reference_);
232+
}
233+
234+
sort_by_reference_impl(std::index_sequence_for<Ts...>{});
235+
}
236+
237+
template <size_t... I>
238+
void sort_by_view() {
239+
sort_by_view<I...>([](auto&& a, auto&& b) { return a < b; });
240+
}
241+
217242
void dump(std::basic_ostream<char>& ss) const {
218243
constexpr size_t MAX_NUM_ELEMENTS_TO_PRINT = 25;
219244
size_t num_elements_to_print = size();

0 commit comments

Comments
 (0)