From 5f60c6812101d1b495f53241227a7cf4443cdf08 Mon Sep 17 00:00:00 2001 From: Johannes Barthelmes Date: Thu, 8 Jun 2023 07:22:47 +0200 Subject: [PATCH] Remove dead code --- meson.build | 1 - src/datastructures/qsort.c | 26 ----- src/datastructures/qsort.h | 203 ------------------------------------- src/misc.c | 9 -- src/private_api.h | 6 -- 5 files changed, 245 deletions(-) delete mode 100644 src/datastructures/qsort.c delete mode 100644 src/datastructures/qsort.h diff --git a/meson.build b/meson.build index 389fb6b5bd..d2e27517ba 100644 --- a/meson.build +++ b/meson.build @@ -66,7 +66,6 @@ flecs_src = files( 'src/datastructures/map.c', 'src/datastructures/stack_allocator.c', 'src/datastructures/name_index.c', - 'src/datastructures/qsort.c', 'src/datastructures/sparse.c', 'src/datastructures/strbuf.c', 'src/datastructures/switch_list.c', diff --git a/src/datastructures/qsort.c b/src/datastructures/qsort.c deleted file mode 100644 index 949754c16d..0000000000 --- a/src/datastructures/qsort.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file datastructures/qsort.c - * @brief Quicksort implementation. - */ - -#include "../private_api.h" -#include "qsort.h" - -void ecs_qsort( - void *base, - ecs_size_t nitems, - ecs_size_t size, - int (*compar)(const void *, const void*)) -{ - void *tmp = ecs_os_alloca(size); /* For swap */ - - #define LESS(i, j) \ - compar(ECS_ELEM(base, size, i), ECS_ELEM(base, size, j)) < 0 - - #define SWAP(i, j) \ - ecs_os_memcpy(tmp, ECS_ELEM(base, size, i), size),\ - ecs_os_memcpy(ECS_ELEM(base, size, i), ECS_ELEM(base, size, j), size),\ - ecs_os_memcpy(ECS_ELEM(base, size, j), tmp, size) - - QSORT(nitems, LESS, SWAP); -} diff --git a/src/datastructures/qsort.h b/src/datastructures/qsort.h deleted file mode 100644 index edeadcd59d..0000000000 --- a/src/datastructures/qsort.h +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @file datastructures/qsort.h - * @brief Quicksort implementation. - */ - -/* From: https://github.com/svpv/qsort/blob/master/qsort.h - * Use custom qsort implementation rather than relying on the version in libc to - * ensure that results are consistent across platforms. - */ - -/* - * Copyright (c) 2013, 2017 Alexey Tourbin - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * This is a traditional Quicksort implementation which mostly follows - * [Sedgewick 1978]. Sorting is performed entirely on array indices, - * while actual access to the array elements is abstracted out with the - * user-defined `LESS` and `SWAP` primitives. - * - * Synopsis: - * QSORT(N, LESS, SWAP); - * where - * N - the number of elements in A[]; - * LESS(i, j) - compares A[i] to A[j]; - * SWAP(i, j) - exchanges A[i] with A[j]. - */ - -#ifndef QSORT_H -#define QSORT_H - -/* Sort 3 elements. */ -#define Q_SORT3(q_a1, q_a2, q_a3, Q_LESS, Q_SWAP) \ -do { \ - if (Q_LESS(q_a2, q_a1)) { \ - if (Q_LESS(q_a3, q_a2)) \ - Q_SWAP(q_a1, q_a3); \ - else { \ - Q_SWAP(q_a1, q_a2); \ - if (Q_LESS(q_a3, q_a2)) \ - Q_SWAP(q_a2, q_a3); \ - } \ - } \ - else if (Q_LESS(q_a3, q_a2)) { \ - Q_SWAP(q_a2, q_a3); \ - if (Q_LESS(q_a2, q_a1)) \ - Q_SWAP(q_a1, q_a2); \ - } \ -} while (0) - -/* Partition [q_l,q_r] around a pivot. After partitioning, - * [q_l,q_j] are the elements that are less than or equal to the pivot, - * while [q_i,q_r] are the elements greater than or equal to the pivot. */ -#define Q_PARTITION(q_l, q_r, q_i, q_j, Q_UINT, Q_LESS, Q_SWAP) \ -do { \ - /* The middle element, not to be confused with the median. */ \ - Q_UINT q_m = q_l + ((q_r - q_l) >> 1); \ - /* Reorder the second, the middle, and the last items. \ - * As [Edelkamp Weiss 2016] explain, using the second element \ - * instead of the first one helps avoid bad behaviour for \ - * decreasingly sorted arrays. This method is used in recent \ - * versions of gcc's std::sort, see gcc bug 58437#c13, although \ - * the details are somewhat different (cf. #c14). */ \ - Q_SORT3(q_l + 1, q_m, q_r, Q_LESS, Q_SWAP); \ - /* Place the median at the beginning. */ \ - Q_SWAP(q_l, q_m); \ - /* Partition [q_l+2, q_r-1] around the median which is in q_l. \ - * q_i and q_j are initially off by one, they get decremented \ - * in the do-while loops. */ \ - q_i = q_l + 1; q_j = q_r; \ - while (1) { \ - do q_i++; while (Q_LESS(q_i, q_l)); \ - do q_j--; while (Q_LESS(q_l, q_j)); \ - if (q_i >= q_j) break; /* Sedgewick says "until j < i" */ \ - Q_SWAP(q_i, q_j); \ - } \ - /* Compensate for the i==j case. */ \ - q_i = q_j + 1; \ - /* Put the median to its final place. */ \ - Q_SWAP(q_l, q_j); \ - /* The median is not part of the left subfile. */ \ - q_j--; \ -} while (0) - -/* Insertion sort is applied to small subfiles - this is contrary to - * Sedgewick's suggestion to run a separate insertion sort pass after - * the partitioning is done. The reason I don't like a separate pass - * is that it triggers extra comparisons, because it can't see that the - * medians are already in their final positions and need not be rechecked. - * Since I do not assume that comparisons are cheap, I also do not try - * to eliminate the (q_j > q_l) boundary check. */ -#define Q_INSERTION_SORT(q_l, q_r, Q_UINT, Q_LESS, Q_SWAP) \ -do { \ - Q_UINT q_i, q_j; \ - /* For each item starting with the second... */ \ - for (q_i = q_l + 1; q_i <= q_r; q_i++) \ - /* move it down the array so that the first part is sorted. */ \ - for (q_j = q_i; q_j > q_l && (Q_LESS(q_j, q_j - 1)); q_j--) \ - Q_SWAP(q_j, q_j - 1); \ -} while (0) - -/* When the size of [q_l,q_r], i.e. q_r-q_l+1, is greater than or equal to - * Q_THRESH, the algorithm performs recursive partitioning. When the size - * drops below Q_THRESH, the algorithm switches to insertion sort. - * The minimum valid value is probably 5 (with 5 items, the second and - * the middle items, the middle itself being rounded down, are distinct). */ -#define Q_THRESH 16 - -/* The main loop. */ -#define Q_LOOP(Q_UINT, Q_N, Q_LESS, Q_SWAP) \ -do { \ - Q_UINT q_l = 0; \ - Q_UINT q_r = (Q_N) - 1; \ - Q_UINT q_sp = 0; /* the number of frames pushed to the stack */ \ - struct { Q_UINT q_l, q_r; } \ - /* On 32-bit platforms, to sort a "char[3GB+]" array, \ - * it may take full 32 stack frames. On 64-bit CPUs, \ - * though, the address space is limited to 48 bits. \ - * The usage is further reduced if Q_N has a 32-bit type. */ \ - q_st[sizeof(Q_UINT) > 4 && sizeof(Q_N) > 4 ? 48 : 32]; \ - while (1) { \ - if (q_r - q_l + 1 >= Q_THRESH) { \ - Q_UINT q_i, q_j; \ - Q_PARTITION(q_l, q_r, q_i, q_j, Q_UINT, Q_LESS, Q_SWAP); \ - /* Now have two subfiles: [q_l,q_j] and [q_i,q_r]. \ - * Dealing with them depends on which one is bigger. */ \ - if (q_j - q_l >= q_r - q_i) \ - Q_SUBFILES(q_l, q_j, q_i, q_r); \ - else \ - Q_SUBFILES(q_i, q_r, q_l, q_j); \ - } \ - else { \ - Q_INSERTION_SORT(q_l, q_r, Q_UINT, Q_LESS, Q_SWAP); \ - /* Pop subfiles from the stack, until it gets empty. */ \ - if (q_sp == 0) break; \ - q_sp--; \ - q_l = q_st[q_sp].q_l; \ - q_r = q_st[q_sp].q_r; \ - } \ - } \ -} while (0) - -/* The missing part: dealing with subfiles. - * Assumes that the first subfile is not smaller than the second. */ -#define Q_SUBFILES(q_l1, q_r1, q_l2, q_r2) \ -do { \ - /* If the second subfile is only a single element, it needs \ - * no further processing. The first subfile will be processed \ - * on the next iteration (both subfiles cannot be only a single \ - * element, due to Q_THRESH). */ \ - if (q_l2 == q_r2) { \ - q_l = q_l1; \ - q_r = q_r1; \ - } \ - else { \ - /* Otherwise, both subfiles need processing. \ - * Push the larger subfile onto the stack. */ \ - q_st[q_sp].q_l = q_l1; \ - q_st[q_sp].q_r = q_r1; \ - q_sp++; \ - /* Process the smaller subfile on the next iteration. */ \ - q_l = q_l2; \ - q_r = q_r2; \ - } \ -} while (0) - -/* And now, ladies and gentlemen, may I proudly present to you... */ -#define QSORT(Q_N, Q_LESS, Q_SWAP) \ -do { \ - if ((Q_N) > 1) \ - /* We could check sizeof(Q_N) and use "unsigned", but at least \ - * on x86_64, this has the performance penalty of up to 5%. */ \ - Q_LOOP(ecs_size_t, Q_N, Q_LESS, Q_SWAP); \ -} while (0) - -void ecs_qsort( - void *base, - ecs_size_t nitems, - ecs_size_t size, - int (*compar)(const void *, const void*)); - -#define ecs_qsort_t(base, nitems, T, compar) \ - ecs_qsort(base, nitems, ECS_SIZEOF(T), compar) - -#endif diff --git a/src/misc.c b/src/misc.c index 927ff45625..acc7a1971f 100644 --- a/src/misc.c +++ b/src/misc.c @@ -127,15 +127,6 @@ int flecs_entity_compare( return (e1 > e2) - (e1 < e2); } -int flecs_entity_compare_qsort( - const void *e1, - const void *e2) -{ - ecs_entity_t v1 = *(ecs_entity_t*)e1; - ecs_entity_t v2 = *(ecs_entity_t*)e2; - return flecs_entity_compare(v1, NULL, v2, NULL); -} - uint64_t flecs_string_hash( const void *ptr) { diff --git a/src/private_api.h b/src/private_api.h index f9801d5a6e..7fb97d65f3 100644 --- a/src/private_api.h +++ b/src/private_api.h @@ -15,7 +15,6 @@ #include "poly.h" #include "stage.h" #include "world.h" -#include "datastructures/qsort.h" #include "datastructures/name_index.h" @@ -277,11 +276,6 @@ int flecs_entity_compare( ecs_entity_t e2, const void *ptr2); -/* Compare function for entity ids which can be used with qsort */ -int flecs_entity_compare_qsort( - const void *e1, - const void *e2); - bool flecs_name_is_id( const char *name);