/* Piles smaller than this are handled with a simple insertion sort. */ #define INSERTION_SORT_THRESHOLD 12
/* Sort keys are pointers to immutable fixed-length arrays of bytes. */ typedefconst u8 *sort_key_t;
/* *Thekeysareseparatedintopilesbasedonthebyteineachkeysatthecurrentoffset,sothe *numberofkeyswitheachbytemustbecounted.
*/ struct histogram { /* The number of non-empty bins */
u16 used; /* The index (key byte) of the first non-empty bin */
u16 first; /* The index (key byte) of the last non-empty bin */
u16 last; /* The number of occurrences of each specific byte */
u32 size[256];
};
/* *Sub-tasksaremanuallymanagedonastack,bothforperformanceandtoputalogarithmicbound *onthestackspaceneeded.
*/ struct task { /* Pointer to the first key to sort. */
sort_key_t *first_key; /* Pointer to the last key to sort. */
sort_key_t *last_key; /* The offset into the key at which to continue sorting. */
u16 offset; /* The number of bytes remaining in the sort keys. */
u16 length;
};
/* Compare a segment of two fixed-length keys starting at an offset. */ staticinlineint compare(sort_key_t key1, sort_key_t key2, u16 offset, u16 length)
{ return memcmp(&key1[offset], &key2[offset], length);
}
/* Insert the next unsorted key into an array of sorted keys. */ staticinlinevoid insert_key(conststruct task task, sort_key_t *next)
{ /* Pull the unsorted key out, freeing up the array slot. */
sort_key_t unsorted = *next;
/* Compare the key to the preceding sorted entries, shifting down ones that are larger. */ while ((--next >= task.first_key) &&
(compare(unsorted, next[0], task.offset, task.length) < 0))
next[1] = next[0];
/* Insert the key into the last slot that was cleared, sorting it. */
next[1] = unsorted;
}
for (key_ptr = task.first_key; key_ptr <= task.last_key; key_ptr++) { /* Increment the count for the byte in the key at the current offset. */
u8 bin = (*key_ptr)[task.offset];
u32 size = ++bins->size[bin];
/* Track non-empty bins. */ if (size == 1) {
bins->used += 1; if (bin < bins->first)
bins->first = bin;
/* All zero-length keys are identical and therefore already sorted. */ if ((count == 0) || (length == 0)) return UDS_SUCCESS;
/* The initial task is to sort the entire length of all the keys. */
start = (struct task) {
.first_key = keys,
.last_key = &keys[count - 1],
.offset = 0,
.length = length,
};
if (count <= INSERTION_SORT_THRESHOLD) {
insertion_sort(start); return UDS_SUCCESS;
}
if (count > sorter->count) return UDS_INVALID_ARGUMENT;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.