Skip to content

Commit b048d1e

Browse files
committed
Optionally sort a DetSet elements with a cached key
Add a unit test for the new functionality.
1 parent e04f43e commit b048d1e

File tree

3 files changed

+466
-8
lines changed

3 files changed

+466
-8
lines changed

DataFormats/Common/interface/DetSetVector.h

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,71 @@ behavior (usually a core dump).
3737

3838
#include <algorithm>
3939
#include <iterator>
40+
#include <numeric>
41+
#include <type_traits>
4042
#include <vector>
4143

42-
#include <type_traits>
43-
#include "boost/concept_check.hpp"
44+
#include <boost/concept_check.hpp>
4445

46+
#include "DataFormats/Common/interface/BoolCache.h"
4547
#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
4648
#include "DataFormats/Common/interface/DetSet.h"
4749
#include "DataFormats/Common/interface/FillView.h"
4850
#include "DataFormats/Common/interface/Ref.h"
4951
#include "DataFormats/Common/interface/traits.h"
50-
5152
#include "FWCore/Utilities/interface/EDMException.h"
5253

53-
#include "DataFormats/Common/interface/BoolCache.h"
54-
5554
namespace edm {
55+
56+
namespace detail {
57+
58+
// from https://devblogs.microsoft.com/oldnewthing/20170104-00/?p=95115
59+
60+
template <typename Iter1, typename Iter2>
61+
void apply_permutation(Iter1 first, Iter1 last, Iter2 indices) {
62+
using T = std::iterator_traits<Iter1>::value_type;
63+
using Diff = std::iterator_traits<Iter2>::value_type;
64+
Diff length = last - first;
65+
for (Diff i = 0; i < length; i++) {
66+
Diff current = i;
67+
if (i != indices[current]) {
68+
T t{std::move(first[i])};
69+
while (i != indices[current]) {
70+
Diff next = indices[current];
71+
first[current] = std::move(first[next]);
72+
indices[current] = current;
73+
current = next;
74+
}
75+
first[current] = std::move(t);
76+
indices[current] = current;
77+
}
78+
}
79+
}
80+
81+
// from https://devblogs.microsoft.com/oldnewthing/20170106-00/?p=95135
82+
83+
template <typename Iter, typename UnaryOperation, typename Compare>
84+
void sort_by_key(Iter first, Iter last, UnaryOperation op, Compare comp) {
85+
using Diff = std::iterator_traits<Iter>::difference_type;
86+
using T = std::iterator_traits<Iter>::value_type;
87+
using Key = decltype(op(std::declval<T>()));
88+
Diff length = std::distance(first, last);
89+
std::vector<Key> keys;
90+
keys.reserve(length);
91+
std::transform(first, last, std::back_inserter(keys), [&](T& t) { return op(t); });
92+
std::vector<Diff> indices(length);
93+
std::iota(indices.begin(), indices.end(), static_cast<Diff>(0));
94+
std::sort(indices.begin(), indices.end(), [&](Diff a, Diff b) { return comp(keys[a], keys[b]); });
95+
apply_permutation(first, last, indices.begin());
96+
}
97+
98+
template <typename Iter, typename UnaryOperation>
99+
void sort_by_key(Iter first, Iter last, UnaryOperation op) {
100+
sort_by_key(first, last, op, std::less<>());
101+
}
102+
103+
} // namespace detail
104+
56105
class ProductID;
57106

58107
//------------------------------------------------------------
@@ -340,7 +389,11 @@ namespace edm {
340389
for (; i != e; ++i) {
341390
i->data.shrink_to_fit();
342391
// sort the Detset pointed to by
343-
std::sort(i->data.begin(), i->data.end());
392+
if constexpr (requires(const T& t) { t.sort_key(); }) {
393+
edm::detail::sort_by_key(i->data.begin(), i->data.end(), [](const T& t) { return t.sort_key(); });
394+
} else {
395+
std::sort(i->data.begin(), i->data.end());
396+
}
344397
}
345398
}
346399

DataFormats/Common/test/BuildFile.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
<bin name="testDataFormatsCommon" file="testRunner.cpp,testOwnVector.cc,testOneToOneAssociation.cc,testValueMap.cc,testOneToManyAssociation.cc,testAssociationVector.cc,testAssociationNew.cc,testValueMapNew.cc,testSortedCollection.cc,testRangeMap.cc,ref_t.cppunit.cc,DetSetRefVector_t.cppunit.cc,reftobasevector_t.cppunit.cc,cloningptr_t.cppunit.cc,ptr_t.cppunit.cc,ptrvector_t.cppunit.cc,containermask_t.cppunit.cc,reftobaseprod_t.cppunit.cc,handle_t.cppunit.cc">
1515
</bin>
1616

17-
<bin name="testDataFormatsCommonCatch2" file="DetSetVector_t.cpp,exDSTV.cpp,exTrie.cpp,OwnVector_t.cpp,Wrapper_t.cpp,testBoostRange.cpp,reftobase_t.cpp,">
18-
<use name="catch2"/>
17+
<bin name="testDataFormatsCommonCatch2" file="DetSetVector_t.cpp,DetSetVectorWithKey_t.cpp,exDSTV.cpp,exTrie.cpp,OwnVector_t.cpp,Wrapper_t.cpp,testBoostRange.cpp,reftobase_t.cpp">
18+
<use name="catch2"/>
1919
</bin>
2020

2121
<bin file="DictionaryTools_t.cpp">

0 commit comments

Comments
 (0)