168 size_t si = 0, di = 0; |
168 size_t si = 0, di = 0; |
169 char const *src = sorted_data; |
169 char const *src = sorted_data; |
170 char *dest = *target; |
170 char *dest = *target; |
171 |
171 |
172 // find the first insertion point |
172 // find the first insertion point |
173 while (di < old_size) { |
173 di = cx_array_binary_search_sup(dest, old_size, elem_size, src, cmp_func); |
174 if (cmp_func(src, dest) < 0) { |
174 dest += di * elem_size; |
175 break; |
|
176 } |
|
177 di++; |
|
178 dest += elem_size; |
|
179 } |
|
180 |
175 |
181 // move the remaining elements in the array completely to the right |
176 // move the remaining elements in the array completely to the right |
182 // we will call it the "buffer" for parked elements |
177 // we will call it the "buffer" for parked elements |
183 size_t buf_size = old_size - di; |
178 size_t buf_size = old_size - di; |
184 size_t bi = new_size - buf_size; |
179 size_t bi = new_size - buf_size; |
187 |
182 |
188 // while there are both source and buffered elements left, |
183 // while there are both source and buffered elements left, |
189 // copy them interleaving |
184 // copy them interleaving |
190 while (si < elem_count && bi < new_size) { |
185 while (si < elem_count && bi < new_size) { |
191 // determine how many source elements can be inserted |
186 // determine how many source elements can be inserted |
192 size_t copy_len = 1; |
187 size_t copy_len, bytes_copied; |
193 si++; |
188 copy_len = cx_array_binary_search_sup( |
194 char const *next_src = src + elem_size; |
189 src, |
195 while (si < elem_count) { |
190 elem_count - si, |
196 if (cmp_func(bptr, next_src) < 0) { |
191 elem_size, |
197 break; |
192 bptr, |
198 } |
193 cmp_func |
199 copy_len++; |
194 ); |
200 si++; |
|
201 next_src += elem_size; |
|
202 } |
|
203 |
195 |
204 // copy the source elements |
196 // copy the source elements |
205 memcpy(dest, src, copy_len * elem_size); |
197 bytes_copied = copy_len * elem_size; |
206 dest += copy_len * elem_size; |
198 memcpy(dest, src, bytes_copied); |
207 src = next_src; |
199 dest += bytes_copied; |
|
200 src += bytes_copied; |
|
201 si += copy_len; |
|
202 |
|
203 // when all source elements are in place, we are done |
|
204 if (si >= elem_count) break; |
208 |
205 |
209 // determine how many buffered elements need to be restored |
206 // determine how many buffered elements need to be restored |
210 copy_len = 1; |
207 copy_len = cx_array_binary_search_sup( |
211 bi++; |
208 bptr, |
212 char *next_bptr = bptr + elem_size; |
209 new_size - bi, |
213 while (bi < new_size) { |
210 elem_size, |
214 if (cmp_func(src, next_bptr) < 0) { |
211 src, |
215 break; |
212 cmp_func |
216 } |
213 ); |
217 copy_len++; |
|
218 bi++; |
|
219 next_bptr += elem_size; |
|
220 } |
|
221 |
214 |
222 // restore the buffered elements |
215 // restore the buffered elements |
223 memmove(dest, bptr, copy_len * elem_size); |
216 bytes_copied = copy_len * elem_size; |
224 dest += copy_len * elem_size; |
217 memmove(dest, bptr, bytes_copied); |
225 bptr = next_bptr; |
218 dest += bytes_copied; |
|
219 bptr += bytes_copied; |
|
220 bi += copy_len; |
226 } |
221 } |
227 |
222 |
228 // still source elements left? simply append them |
223 // still source elements left? simply append them |
229 if (si < elem_count) { |
224 if (si < elem_count) { |
230 memcpy(dest, src, elem_size * (elem_count - si)); |
225 memcpy(dest, src, elem_size * (elem_count - si)); |