Compare commits
No commits in common. "0b974f624268154ad239fcad99ee078d65c88b49" and "f8d4f597c6c025ce2175661841774d2844737221" have entirely different histories.
0b974f6242
...
f8d4f597c6
97
magyarsort.h
97
magyarsort.h
@ -9,9 +9,9 @@
|
|||||||
* LICENCE: CC3 - look it up, you need to mention me but that is all
|
* LICENCE: CC3 - look it up, you need to mention me but that is all
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring> // memset
|
|
||||||
|
|
||||||
namespace MagyarSort {
|
namespace MagyarSort {
|
||||||
|
|
||||||
@ -23,67 +23,44 @@ namespace MagyarSort {
|
|||||||
// - DIGIT_RANGE and BITS_PER_DIGIT should correspond
|
// - DIGIT_RANGE and BITS_PER_DIGIT should correspond
|
||||||
// - DIGITS should also correspond with the uint32_t
|
// - DIGITS should also correspond with the uint32_t
|
||||||
// - and DIGIT_RANGE should be 2^n value (16 or 256)
|
// - and DIGIT_RANGE should be 2^n value (16 or 256)
|
||||||
static constexpr int DIGITS = 8; // "helyiérték"
|
static constexpr int DIGITS = 4; // "helyiérték"
|
||||||
static constexpr int BITS_PER_DIGIT = 4; // "bit / helyiérték"
|
static constexpr int BITS_PER_DIGIT = 8; // "bit / helyiérték"
|
||||||
static constexpr int DIGIT_RANGE = 16; // "helyiérték állapottér"
|
static constexpr int DIGIT_RANGE = 256; // "helyiérték állapottér"
|
||||||
|
|
||||||
template<int DIGIT_CHOICE>
|
template<int digitChoice>
|
||||||
static inline uint32_t getDigit(uint32_t num) noexcept {
|
static inline uint32_t getDigit(uint32_t num) noexcept {
|
||||||
static constexpr int SHIFT = DIGIT_CHOICE * BITS_PER_DIGIT;
|
static constexpr int SHIFT = digitChoice * BITS_PER_DIGIT;
|
||||||
|
|
||||||
uint32_t shifted = num >> SHIFT;
|
uint32_t shifted = num >> SHIFT;
|
||||||
return shifted & (DIGIT_RANGE - 1);
|
return shifted & (DIGIT_RANGE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Recursive Functor: no class should be generated I think (compiler should be smart) */
|
/** Sort the given array (in-place sorting) with the given size */
|
||||||
template<int DIGIT>
|
inline void sort(uint32_t arr[], size_t size) noexcept {
|
||||||
struct OccurenceMagic : public OccurenceMagic<DIGIT - 1> {
|
// Holds "digit" occurences, prefix sums, whatevers
|
||||||
inline OccurenceMagic(uint32_t arr[], size_t i, size_t *radicsOut) noexcept
|
// First "DIGIT_RANGE" elem is for MSB "DIGITS", last is for LSB
|
||||||
: OccurenceMagic<DIGIT -1 >(arr, i, radicsOut) {
|
static thread_local size_t radics[DIGITS * DIGIT_RANGE];
|
||||||
// Parents run first so template recursion runs DIGIT=0 first...
|
for(int i = 0; i < (DIGITS * DIGIT_RANGE); ++i) { radics[i] = 0; }
|
||||||
++radicsOut[getDigit<DIGIT>(arr[i]) + DIGIT_RANGE * DIGIT];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/** Ends template recursion */
|
|
||||||
template<>
|
|
||||||
struct OccurenceMagic<-1> {
|
|
||||||
inline OccurenceMagic(uint32_t arr[], size_t i, size_t *radicsOut) noexcept {}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void countOccurences(uint32_t arr[], size_t size, size_t *radicsOut) noexcept {
|
// Calculate occurences of digits
|
||||||
for(size_t i = 0; i < size; ++i) {
|
for(size_t i = 0; i < size; ++i) {
|
||||||
// Creates no object, struct is empty
|
auto d0 = getDigit<0>(arr[i]);
|
||||||
OccurenceMagic<DIGITS - 1>(arr, i, radicsOut);
|
auto d1 = getDigit<1>(arr[i]);
|
||||||
}
|
auto d2 = getDigit<2>(arr[i]);
|
||||||
|
auto d3 = getDigit<3>(arr[i]);
|
||||||
|
|
||||||
|
printf("d0:%u, arr[i]: %u\n", d0, arr[i]);
|
||||||
|
printf("d1:%u, arr[i]: %u\n", d1, arr[i]);
|
||||||
|
printf("d2:%u, arr[i]: %u\n", d2, arr[i]);
|
||||||
|
printf("d3:%u, arr[i]: %u\n", d3, arr[i]);
|
||||||
|
|
||||||
|
++radics[d0];
|
||||||
|
++radics[d1 + DIGIT_RANGE * 1];
|
||||||
|
++radics[d2 + DIGIT_RANGE * 2];
|
||||||
|
++radics[d3 + DIGIT_RANGE * 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Recursive Functor: no class should be generated I think (compiler should be smart) */
|
// TODO: remove debug stuffz
|
||||||
template<int DIGIT>
|
|
||||||
struct PrefixMagic : public PrefixMagic<DIGIT - 1> {
|
|
||||||
inline PrefixMagic(size_t *radics, size_t *prev, int i) noexcept
|
|
||||||
: PrefixMagic<DIGIT - 1>(radics, prev, i) {
|
|
||||||
static constexpr int DSTART = (DIGIT * DIGIT_RANGE);
|
|
||||||
radics[DSTART + i] += prev[DIGIT];
|
|
||||||
prev[DIGIT] = radics[DSTART + i];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/** Ends template recursion */
|
|
||||||
template<>
|
|
||||||
struct PrefixMagic<-1> {
|
|
||||||
inline PrefixMagic(size_t *radics, size_t *prev, int i) noexcept {}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void calcPrefixSums(size_t *radics) noexcept {
|
|
||||||
static thread_local size_t prev[DIGITS];
|
|
||||||
memset(prev, 0, sizeof(prev));
|
|
||||||
|
|
||||||
for(int i = 0; i < DIGIT_RANGE; ++i) {
|
|
||||||
// This is a template-unrolled loop too
|
|
||||||
PrefixMagic<DIGITS - 1>(radics, prev, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void debugIt(size_t *radics) {
|
|
||||||
for(size_t j = 0; j < DIGITS; ++j) {
|
for(size_t j = 0; j < DIGITS; ++j) {
|
||||||
printf("d%d: ", j);
|
printf("d%d: ", j);
|
||||||
for(size_t i = 0; i < DIGIT_RANGE; ++i) {
|
for(size_t i = 0; i < DIGIT_RANGE; ++i) {
|
||||||
@ -92,24 +69,6 @@ namespace MagyarSort {
|
|||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sort the given array (in-place sorting) with the given size */
|
|
||||||
inline void sort(uint32_t arr[], size_t size) noexcept {
|
|
||||||
// Holds "digit" occurences, prefix sums, whatevers
|
|
||||||
// First "DIGIT_RANGE" elem is for MSB "DIGITS", last is for LSB
|
|
||||||
static thread_local size_t radics[DIGITS * DIGIT_RANGE];
|
|
||||||
memset(radics, 0, sizeof(radics));
|
|
||||||
|
|
||||||
// Calculate occurences of digits
|
|
||||||
countOccurences(arr, size, radics);
|
|
||||||
|
|
||||||
debugIt(radics);
|
|
||||||
|
|
||||||
// Calculate prefix sums
|
|
||||||
calcPrefixSums(radics);
|
|
||||||
|
|
||||||
debugIt(radics);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user