|
@@ -132,27 +132,21 @@ static void *move_sorted(void *voidargs)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// As above, but the first Nr msg_size-byte entries in the items array
|
|
|
-// will end up with the sorted values. Note: if Nr < Na, entries beyond
|
|
|
-// Nr may also change, but you should not even look at those values!
|
|
|
-// This calls the above function, and then copies the data in sorted
|
|
|
-// order into a temporary buffer, then copies that buffer back into the
|
|
|
-// items array, so it's less efficient, both in memory and CPU, than the
|
|
|
-// above function.
|
|
|
+// As above, but also pass an Nr*msg_size-byte buffer outbuf to put
|
|
|
+// the sorted values into, instead of passing a callback. This calls
|
|
|
+// the above function, then copies the data in sorted order into outbuf.
|
|
|
+// Note: the outbuf buffer cannot overlap the items buffer.
|
|
|
template<typename T>
|
|
|
void sort_mtobliv(threadid_t nthreads, uint8_t* items, uint16_t msg_size,
|
|
|
- uint32_t Nr, uint32_t Na)
|
|
|
+ uint32_t Nr, uint32_t Na, uint8_t *outbuf)
|
|
|
{
|
|
|
- sort_mtobliv<T>(nthreads, items, msg_size, Nr, Na, [nthreads, msg_size]
|
|
|
+ sort_mtobliv<T>(nthreads, items, msg_size, Nr, Na,
|
|
|
+ [nthreads, msg_size, outbuf]
|
|
|
(const uint8_t* origitems, const T* keys, uint32_t Nr) {
|
|
|
- // A temporary buffer into which to copy the items in sorted
|
|
|
- // order
|
|
|
- uint8_t *tempbuf = new uint8_t[Nr * msg_size];
|
|
|
-
|
|
|
// Special-case nthreads=1 for efficiency
|
|
|
if (nthreads <= 1) {
|
|
|
move_sorted_args<T> args = {
|
|
|
- keys, origitems, tempbuf, 0, Nr, msg_size
|
|
|
+ keys, origitems, outbuf, 0, Nr, msg_size
|
|
|
};
|
|
|
move_sorted<T>(&args);
|
|
|
} else {
|
|
@@ -163,7 +157,7 @@ void sort_mtobliv(threadid_t nthreads, uint8_t* items, uint16_t msg_size,
|
|
|
for (threadid_t i=0; i<nthreads; ++i) {
|
|
|
uint32_t num = inc + (i < extra);
|
|
|
args[i] = {
|
|
|
- keys, origitems, tempbuf, last, num, msg_size
|
|
|
+ keys, origitems, outbuf, last, num, msg_size
|
|
|
};
|
|
|
last += num;
|
|
|
}
|
|
@@ -182,9 +176,21 @@ void sort_mtobliv(threadid_t nthreads, uint8_t* items, uint16_t msg_size,
|
|
|
threadpool_join(g_thread_id+i, NULL);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // Copy the temporary buffer back to items
|
|
|
- memmove(origitems, tempbuf, Nr * msg_size);
|
|
|
- delete[] tempbuf;
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+// As above, but the first Nr msg_size-byte entries in the items array
|
|
|
+// will end up with the sorted values. Note: if Nr < Na, entries beyond
|
|
|
+// Nr may also change, but you should not even look at those values!
|
|
|
+// This calls the above function with a temporary buffer, then copies
|
|
|
+// that buffer back into the items array, so it's less efficient, both
|
|
|
+// in memory and CPU, than the above functions.
|
|
|
+template<typename T>
|
|
|
+void sort_mtobliv(threadid_t nthreads, uint8_t* items, uint16_t msg_size,
|
|
|
+ uint32_t Nr, uint32_t Na)
|
|
|
+{
|
|
|
+ uint8_t *tempbuf = new uint8_t[Nr * msg_size];
|
|
|
+ sort_mtobliv<T>(nthreads, items, msg_size, Nr, Na, tempbuf);
|
|
|
+ memmove(items, tempbuf, Nr * msg_size);
|
|
|
+ delete[] tempbuf;
|
|
|
+}
|