diff options
author | George Hazan <george.hazan@gmail.com> | 2015-07-26 13:43:27 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2015-07-26 13:43:27 +0000 |
commit | 38f9ee31afcb519f7ecba02b56737ae637de5c7a (patch) | |
tree | 98a676cd76c8897c1a12ae69a4a3c740ac5cc065 /protocols | |
parent | f4af257e9365602dc81a4b324b0ffeed1e0b2eef (diff) |
more warning fixes
git-svn-id: http://svn.miranda-ng.org/main/trunk@14728 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/Sametime/src/glib/gqsort.c | 376 |
1 files changed, 181 insertions, 195 deletions
diff --git a/protocols/Sametime/src/glib/gqsort.c b/protocols/Sametime/src/glib/gqsort.c index f0acecfe89..25508167f9 100644 --- a/protocols/Sametime/src/glib/gqsort.c +++ b/protocols/Sametime/src/glib/gqsort.c @@ -45,33 +45,33 @@ /* Byte-wise swap two items of size SIZE. */ #define SWAP(a, b, size) \ do \ - { \ + { \ register size_t __size = (size); \ register char *__a = (a), *__b = (b); \ do \ - { \ + { \ char __tmp = *__a; \ *__a++ = *__b; \ *__b++ = __tmp; \ - } while (--__size > 0); \ - } while (0) + } while (--__size > 0); \ + } while (0) /* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ + This particular magic number was chosen to work best on a Sun 4/260. */ #define MAX_THRESH 4 /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct - { - char *lo; - char *hi; - } stack_node; +{ + char *lo; + char *hi; +} stack_node; /* The next 4 #defines implement a very fast in-line stack abstraction. */ /* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type size_t, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(size_t). */ + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ #define STACK_SIZE (CHAR_BIT * sizeof(size_t)) #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) @@ -79,28 +79,28 @@ typedef struct /* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: + four optimizations discussed in Sedgewick: - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ /** * g_qsort_with_data: @@ -112,174 +112,160 @@ typedef struct * * This is just like the standard C qsort() function, but * the comparison routine accepts a user data argument. - * + * **/ void -g_qsort_with_data (gconstpointer pbase, - gint total_elems, - gsize size, - GCompareDataFunc compare_func, - gpointer user_data) +g_qsort_with_data(gconstpointer pbase, +gint total_elems, +gsize size, +GCompareDataFunc compare_func, +gpointer user_data) { - register char *base_ptr = (char *) pbase; - - const size_t max_thresh = MAX_THRESH * size; - - g_return_if_fail (total_elems >= 0); - g_return_if_fail (pbase != NULL || total_elems == 0); - g_return_if_fail (compare_func != NULL); - - if (total_elems == 0) - /* Avoid lossage with unsigned arithmetic below. */ - return; - - if (total_elems > MAX_THRESH) - { - char *lo = base_ptr; - char *hi = &lo[size * (total_elems - 1)]; - stack_node stack[STACK_SIZE]; - stack_node *top = stack; - - PUSH (NULL, NULL); - - while (STACK_NOT_EMPTY) - { - char *left_ptr; - char *right_ptr; - - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR in - the while loops. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*compare_func) ((void *) mid, (void *) lo, user_data) < 0) - SWAP (mid, lo, size); - if ((*compare_func) ((void *) hi, (void *) mid, user_data) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*compare_func) ((void *) mid, (void *) lo, user_data) < 0) - SWAP (mid, lo, size); - jump_over:; - - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*compare_func) ((void *) left_ptr, (void *) mid, user_data) < 0) - left_ptr += size; - - while ((*compare_func) ((void *) mid, (void *) right_ptr, user_data) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; + register char *base_ptr = (char *)pbase; + + const size_t max_thresh = MAX_THRESH * size; + + g_return_if_fail(total_elems >= 0); + g_return_if_fail(pbase != NULL || total_elems == 0); + g_return_if_fail(compare_func != NULL); + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + stack_node *top = stack; + + PUSH(NULL, NULL); + + while (STACK_NOT_EMPTY) { + char *left_ptr; + char *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*compare_func) ((void *)mid, (void *)lo, user_data) < 0) + SWAP(mid, lo, size); + if ((*compare_func) ((void *)hi, (void *)mid, user_data) < 0) + SWAP(mid, hi, size); + else + goto jump_over; + if ((*compare_func) ((void *)mid, (void *)lo, user_data) < 0) + SWAP(mid, lo, size); + jump_over:; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do { + while ((*compare_func) ((void *)left_ptr, (void *)mid, user_data) < 0) + left_ptr += size; + + while ((*compare_func) ((void *)mid, (void *)right_ptr, user_data) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) { + SWAP(left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) { + left_ptr += size; + right_ptr -= size; + break; + } + } while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t)(right_ptr - lo) <= max_thresh) { + if ((size_t)(hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP(lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t)(hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) { + /* Push larger left partition indices. */ + PUSH(lo, right_ptr); + lo = left_ptr; + } + else { + /* Push larger right partition indices. */ + PUSH(left_ptr, hi); + hi = right_ptr; + } } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + register char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*compare_func) ((void *)run_ptr, (void *)tmp_ptr, user_data) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP(tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) { + tmp_ptr = run_ptr - size; + while ((*compare_func) ((void *)run_ptr, (void *)tmp_ptr, user_data) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } } - } - while (left_ptr <= right_ptr); - - /* Set up pointers for next iteration. First determine whether - left and right partitions are below the threshold size. If so, - ignore one or both. Otherwise, push the larger partition's - bounds on the stack and continue sorting the smaller one. */ - - if ((size_t) (right_ptr - lo) <= max_thresh) - { - if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ - POP (lo, hi); - else - /* Ignore small left partition. */ - lo = left_ptr; - } - else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ - hi = right_ptr; - else if ((right_ptr - lo) > (hi - left_ptr)) - { - /* Push larger left partition indices. */ - PUSH (lo, right_ptr); - lo = left_ptr; - } - else - { - /* Push larger right partition indices. */ - PUSH (left_ptr, hi); - hi = right_ptr; - } - } - } - - /* Once the BASE_PTR array is partially sorted by quicksort the rest - is completely sorted using insertion sort, since this is efficient - for partitions below MAX_THRESH size. BASE_PTR points to the beginning - of the array to sort, and END_PTR points at the very last element in - the array (*not* one beyond it!). */ - -#define min(x, y) ((x) < (y) ? (x) : (y)) - - { - char *const end_ptr = &base_ptr[size * (total_elems - 1)]; - char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); - register char *run_ptr; - - /* Find smallest element in first threshold and place it at the - array's beginning. This is the smallest array element, - and the operation speeds up insertion sort's inner loop. */ - - for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) - if ((*compare_func) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) - tmp_ptr = run_ptr; - - if (tmp_ptr != base_ptr) - SWAP (tmp_ptr, base_ptr, size); - - /* Insertion sort, running from left-hand-side up to right-hand-side. */ - - run_ptr = base_ptr + size; - while ((run_ptr += size) <= end_ptr) - { - tmp_ptr = run_ptr - size; - while ((*compare_func) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) - tmp_ptr -= size; - - tmp_ptr += size; - if (tmp_ptr != run_ptr) - { - char *trav; - - trav = run_ptr + size; - while (--trav >= run_ptr) - { - char c = *trav; - char *hi, *lo; - - for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) - *hi = *lo; - *hi = c; - } - } - } - } + } } |