annotate foosdk/sdk/pfc/sort.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "pfc-lite.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "sort.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "sort2.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "bit_array_impl.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include "ref_counter.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #if defined(_M_IX86) || defined(_M_IX64)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #include <intrin.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #define PFC_HAVE_RDTSC
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 void swap_void(void * item1,void * item2,t_size width)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 unsigned char * ptr1 = (unsigned char*)item1, * ptr2 = (unsigned char*)item2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 unsigned char temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 for(n=0;n<width;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 temp = *ptr2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 *ptr2 = *ptr1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 *ptr1 = temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 ptr1++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 ptr2++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 void reorder(reorder_callback & p_callback,const t_size * p_order,t_size p_count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 t_size done_size = bit_array_bittable::g_estimate_size(p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 pfc::array_hybrid_t<unsigned char,1024> done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 done.set_size(done_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 pfc::memset_t(done,(unsigned char)0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 for(n=0;n<p_count;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 t_size next = p_order[n];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 if (next!=n && !bit_array_bittable::g_get(done,n))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 t_size prev = n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 do
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 PFC_ASSERT(!bit_array_bittable::g_get(done,next));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 PFC_ASSERT(next>n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 PFC_ASSERT(n<p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 p_callback.swap(prev,next);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 bit_array_bittable::g_set(done,next,true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 prev = next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 next = p_order[next];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 } while(next!=n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 //bit_array_bittable::g_set(done,n,true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 void reorder_void(void * data,t_size width,const t_size * order,t_size num,void (*swapfunc)(void * item1,void * item2,t_size width))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 unsigned char * base = (unsigned char *) data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 t_size done_size = bit_array_bittable::g_estimate_size(num);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 pfc::array_hybrid_t<unsigned char,1024> done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 done.set_size(done_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 pfc::memset_t(done,(unsigned char)0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 for(n=0;n<num;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 t_size next = order[n];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 if (next!=n && !bit_array_bittable::g_get(done,n))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 t_size prev = n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 do
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 PFC_ASSERT(!bit_array_bittable::g_get(done,next));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 PFC_ASSERT(next>n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 PFC_ASSERT(n<num);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 swapfunc(base+width*prev,base+width*next,width);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 bit_array_bittable::g_set(done,next,true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 prev = next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 next = order[next];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 } while(next!=n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 //bit_array_bittable::g_set(done,n,true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 class sort_callback_impl_legacy : public sort_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 sort_callback_impl_legacy(
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 void * p_base,t_size p_width,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 int (*p_comp)(const void *, const void *),
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 void (*p_swap)(void *, void *, t_size)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 ) :
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 m_base((char*)p_base), m_width(p_width),
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 m_comp(p_comp), m_swap(p_swap)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 int compare(t_size p_index1, t_size p_index2) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 return m_comp(m_base + p_index1 * m_width, m_base + p_index2 * m_width);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 void swap(t_size p_index1, t_size p_index2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 m_swap(m_base + p_index1 * m_width, m_base + p_index2 * m_width, m_width);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 char * m_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 t_size m_width;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 int (*m_comp)(const void *, const void *);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 void (*m_swap)(void *, void *, t_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 void sort_void_ex (
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 void *base,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 t_size num,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 t_size width,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 int (*comp)(const void *, const void *),
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 void (*swap)(void *, void *, t_size) )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 sort_callback_impl_legacy cb(base,width,comp,swap);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 sort(cb,num);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 static void squaresort(pfc::sort_callback & p_callback,t_size const p_base,t_size const p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 const t_size max = p_base + p_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 for(t_size walk = p_base + 1; walk < max; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 for(t_size prev = p_base; prev < walk; ++prev) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 p_callback.swap_check(prev,walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 inline static void __sort_2elem_helper(pfc::sort_callback & p_callback,t_size & p_elem1,t_size & p_elem2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 if (p_callback.compare(p_elem1,p_elem2) > 0) pfc::swap_t(p_elem1,p_elem2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 #ifdef PFC_HAVE_RDTSC
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 static inline t_uint64 uniqueVal() {return __rdtsc();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 static counter uniqueValCounter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 static counter::t_val uniqueVal() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 return ++uniqueValCounter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 static t_size myrand(t_size count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 const uint64_t rm = (uint64_t)RAND_MAX + 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 uint64_t m = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 uint64_t v = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 v += rand() * m;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 m *= rm;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 if (m >= count) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 v ^= uniqueVal();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 return (t_size)(v % count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 inline static t_size __pivot_helper(pfc::sort_callback & p_callback,t_size const p_base,t_size const p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 PFC_ASSERT(p_count > 2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 //t_size val1 = p_base, val2 = p_base + (p_count / 2), val3 = p_base + (p_count - 1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 t_size val1 = myrand(p_count), val2 = myrand(p_count-1), val3 = myrand(p_count-2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 if (val2 >= val1) val2++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 if (val3 >= val1) val3++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 if (val3 >= val2) val3++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 val1 += p_base; val2 += p_base; val3 += p_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 __sort_2elem_helper(p_callback,val1,val2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 __sort_2elem_helper(p_callback,val1,val3);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 __sort_2elem_helper(p_callback,val2,val3);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 return val2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 static void newsort(pfc::sort_callback & p_callback,t_size const p_base,t_size const p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 if (p_count <= 4) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 squaresort(p_callback,p_base,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 t_size pivot = __pivot_helper(p_callback,p_base,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 const t_size target = p_base + p_count - 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 if (pivot != target) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 p_callback.swap(pivot,target); pivot = target;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 t_size partition = p_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 bool asdf = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 for(t_size walk = p_base; walk < pivot; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 const int comp = p_callback.compare(walk,pivot);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 bool trigger = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 if (comp == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 trigger = asdf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 asdf = !asdf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 } else if (comp < 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 trigger = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 if (trigger) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 if (partition != walk) p_callback.swap(partition,walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 partition++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 if (pivot != partition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 p_callback.swap(pivot,partition); pivot = partition;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 newsort(p_callback,p_base,pivot-p_base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 newsort(p_callback,pivot+1,p_count-(pivot+1-p_base));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 void sort(pfc::sort_callback & p_callback,t_size p_num) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 srand((unsigned int)(uniqueVal() ^ p_num));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 newsort(p_callback,0,p_num);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 void sort_void(void * base,t_size num,t_size width,int (*comp)(const void *, const void *) )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 sort_void_ex(base,num,width,comp,swap_void);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 sort_callback_stabilizer::sort_callback_stabilizer(sort_callback & p_chain,t_size p_count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 : m_chain(p_chain)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 m_order.set_size(p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 for(n=0;n<p_count;n++) m_order[n] = n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 int sort_callback_stabilizer::compare(t_size p_index1, t_size p_index2) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 int ret = m_chain.compare(p_index1,p_index2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 if (ret == 0) ret = pfc::sgn_t((t_ssize)m_order[p_index1] - (t_ssize)m_order[p_index2]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 void sort_callback_stabilizer::swap(t_size p_index1, t_size p_index2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 m_chain.swap(p_index1,p_index2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 pfc::swap_t(m_order[p_index1],m_order[p_index2]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 void sort_stable(sort_callback & p_callback,t_size p_count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 sort_callback_stabilizer cb(p_callback,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 sort(cb,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 permutation_t make_identitiy(size_t count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 permutation_t ret; ret.set_size_discard(count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 for (size_t walk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 ret[walk] = walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282