Skip to content

Commit 16fe62c

Browse files
committed
Improves test for kv-sort logic
1 parent 6621ac3 commit 16fe62c

File tree

1 file changed

+102
-5
lines changed

1 file changed

+102
-5
lines changed

tests/test-keyvalue.cpp

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,57 @@ class simdkvsort : public ::testing::Test {
2929

3030
TYPED_TEST_SUITE_P(simdkvsort);
3131

32+
template <typename T>
33+
bool same_values(T* v1, T* v2, size_t size){
34+
// Checks that the values are the same except (maybe) their ordering
35+
auto cmp_eq = compare<T, std::equal_to<T>>();
36+
37+
// TODO hardcoding hasnan to true doesn't break anything right?
38+
x86simdsort::qsort(v1, size, true);
39+
x86simdsort::qsort(v2, size, true);
40+
41+
for (size_t i = 0; i < size; i++){
42+
if (!cmp_eq(v1[i], v2[i])){
43+
return false;
44+
}
45+
}
46+
47+
return true;
48+
}
49+
50+
template <typename T1, typename T2>
51+
bool kv_equivalent(T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, size_t size){
52+
auto cmp_eq = compare<T1, std::equal_to<T1>>();
53+
54+
// First check keys are exactly identical
55+
for (size_t i = 0; i < size; i++){
56+
if (!cmp_eq(keys_comp[i], keys_ref[i])){
57+
return false;
58+
}
59+
}
60+
61+
size_t i_start = 0;
62+
T1 key_start = keys_comp[0];
63+
// Loop through all identical keys in a block, then compare the sets of values to make sure they are identical
64+
// We need the index after the loop
65+
size_t i = 0;
66+
for (; i < size; i++){
67+
if (!cmp_eq(keys_comp[i], key_start)){
68+
// Check that every value in
69+
70+
if (!same_values(vals_ref + i_start, vals_comp + i_start, i - i_start)){
71+
return false;
72+
}
73+
74+
// Now setup the start variables to begin gathering keys for the next group
75+
i_start = i;
76+
key_start = keys_comp[i];
77+
}
78+
}
79+
80+
return true;
81+
}
82+
3283
TYPED_TEST_P(simdkvsort, test_kvsort)
3384
{
3485
using T1 = typename std::tuple_element<0, decltype(TypeParam())>::type;
@@ -43,10 +94,10 @@ TYPED_TEST_P(simdkvsort, test_kvsort)
4394
x86simdsort::keyvalue_qsort(key.data(), val.data(), size, hasnan);
4495
xss::scalar::keyvalue_qsort(
4596
key_bckp.data(), val_bckp.data(), size, hasnan);
46-
ASSERT_EQ(key, key_bckp);
47-
const bool hasDuplicates
48-
= std::adjacent_find(key.begin(), key.end()) != key.end();
49-
if (!hasDuplicates) { ASSERT_EQ(val, val_bckp); }
97+
98+
bool is_kv_equivalent = kv_equivalent<T1, T2>(key.data(), val.data(), key_bckp.data(), val_bckp.data(), size);
99+
ASSERT_EQ(is_kv_equivalent, true);
100+
50101
key.clear();
51102
val.clear();
52103
key_bckp.clear();
@@ -55,7 +106,53 @@ TYPED_TEST_P(simdkvsort, test_kvsort)
55106
}
56107
}
57108

58-
REGISTER_TYPED_TEST_SUITE_P(simdkvsort, test_kvsort);
109+
TYPED_TEST_P(simdkvsort, test_validator)
110+
{
111+
// Tests a few edge cases to verify the tests are working correctly and identifying it as functional
112+
using T1 = typename std::tuple_element<0, decltype(TypeParam())>::type;
113+
using T2 = typename std::tuple_element<1, decltype(TypeParam())>::type;
114+
115+
bool is_kv_equivalent;
116+
117+
std::vector<T1> key = {0, 0, 1, 1};
118+
std::vector<T2> val = {1, 2, 3, 4};
119+
std::vector<T1> key_bckp = key;
120+
std::vector<T2> val_bckp = val;
121+
122+
// Duplicate keys, but otherwise exactly identical
123+
is_kv_equivalent = kv_equivalent<T1, T2>(key.data(), val.data(), key_bckp.data(), val_bckp.data(), key.size());
124+
ASSERT_EQ(is_kv_equivalent, true);
125+
126+
val = {2,1,4,3};
127+
128+
// Now values are backwards, but this is still fine
129+
is_kv_equivalent = kv_equivalent<T1, T2>(key.data(), val.data(), key_bckp.data(), val_bckp.data(), key.size());
130+
ASSERT_EQ(is_kv_equivalent, true);
131+
132+
val = {1,3,2,4};
133+
134+
// Now values are mixed up, should fail
135+
is_kv_equivalent = kv_equivalent<T1, T2>(key.data(), val.data(), key_bckp.data(), val_bckp.data(), key.size());
136+
ASSERT_EQ(is_kv_equivalent, false);
137+
138+
val = {1,2,3,4};
139+
key = {0,0,0,0};
140+
141+
// Now keys are messed up, should fail
142+
is_kv_equivalent = kv_equivalent<T1, T2>(key.data(), val.data(), key_bckp.data(), val_bckp.data(), key.size());
143+
ASSERT_EQ(is_kv_equivalent, false);
144+
145+
key = {0,0,0,0,0,0};
146+
key_bckp = key;
147+
val_bckp = {1,2,3,4,5,6};
148+
val = {4,3,1,6,5,2};
149+
150+
// All keys identical, simply reordered values
151+
is_kv_equivalent = kv_equivalent<T1, T2>(key.data(), val.data(), key_bckp.data(), val_bckp.data(), key.size());
152+
ASSERT_EQ(is_kv_equivalent, true);
153+
}
154+
155+
REGISTER_TYPED_TEST_SUITE_P(simdkvsort, test_kvsort, test_validator);
59156

60157
#define CREATE_TUPLES(type) \
61158
std::tuple<double, type>, std::tuple<uint64_t, type>, \

0 commit comments

Comments
 (0)