Dupuis,
On Fri Nov 21 2014 at 12:01:24 AM Steven Ross
Thanks for your input Dupuis.
On Thu Nov 20 2014 at 10:32:46 AM DUPUIS Etienne
wrote: Another example, sorting by birth data and then by name :
// --------------- Start of code snippet ------------------------ struct Id { std::string name; time_t birth;
bool operator<(const Id& id) const { return (birth < id.birth) || ((birth == id.birth) && (name < id.name)); } };
// --------------- End of code snippet ------------------------
Again, I understand that I must use string_sort and split the birth date into 8-bit components. Am I right ?
That's a good idea! I'll add such an example if the library is deemed worthy of including in boost.
I've added such an example to the develop branch that handles signed ints,
signed floats, and multiple string keys all together:
https://github.com/spreadsort/sort/blob/develop/example/generalizedstruct.cp...
And will mention it in the docs. Surprisingly, considering all the
complexity of its get_char function, it's about 50% faster than std::sort
on random data formatted like this. Below are the comparison and get_char
functions for you to see. Comparison sorting is definitely easier, but
hybrid-radix sorting is feasible and surprisingly efficient even for
harder-to-represent cases:
struct DATA_TYPE {
time_t birth;
float net_worth;
string first_name;
string last_name;
};
static const int birth_size = sizeof(time_t);
static const int first_name_offset = birth_size + sizeof(float);
static const boost::uint64_t base_mask = 0xff;
struct lessthan {
inline bool operator()(const DATA_TYPE &x, const DATA_TYPE &y) const {
if (x.birth != y.birth) {
return x.birth < y.birth;
}
if (x.net_worth != y.net_worth) {
return x.net_worth < y.net_worth;
}
if (x.first_name != y.first_name) {
return x.first_name < y.first_name;
}
return x.last_name < y.last_name;
}
};
struct bracket {
inline unsigned char operator()(const DATA_TYPE &x, size_t offset) const {
// Sort date as a signed int, returning the appropriate byte.
if (offset < birth_size) {
const int bit_shift = 8 * (birth_size - offset - 1);
unsigned char result = (x.birth & (base_mask << bit_shift)) >>
bit_shift;
// Handling the sign bit. Unnecessary if the data is always positive.
if (offset == 0) {
return result ^ 128;
}
return result;
}
// Sort a signed float. This requires reversing the order of negatives
// because of the way floats are represented in bits.
if (offset < first_name_offset) {
const int bit_shift = 8 * (first_name_offset - offset - 1);
unsigned key = float_mem_cast