src/list.c

changeset 877
608b14deea18
parent 876
f4ce7df9cff0
equal deleted inserted replaced
876:f4ce7df9cff0 877:608b14deea18
306 size_t cx_list_default_insert_sorted( 306 size_t cx_list_default_insert_sorted(
307 struct cx_list_s *list, 307 struct cx_list_s *list,
308 void const *sorted_data, 308 void const *sorted_data,
309 size_t n 309 size_t n
310 ) { 310 ) {
311 // corner case
312 if (n == 0) return 0;
313
311 size_t elem_size = list->collection.elem_size; 314 size_t elem_size = list->collection.elem_size;
312 cx_compare_func cmp = list->collection.cmpfunc; 315 cx_compare_func cmp = list->collection.cmpfunc;
313 char const *src = sorted_data; 316 char const *src = sorted_data;
314 317
315 size_t r = cx_list_default_insert_array(list, 0, src, n); 318 // track indices and number of inserted items
316 cx_list_default_sort(list); 319 size_t di = 0, si = 0, inserted = 0;
317 320
318 return r; 321 // search the list for insertion points
322 for (; di < list->collection.size; di++) {
323 void const *list_elm = invoke_list_func(at, list, di);
324
325 // compare current list element with first source element
326 // if less or equal, skip
327 if (cmp(list_elm, src) <= 0) {
328 continue;
329 }
330
331 // determine number of consecutive elements that can be inserted
332 size_t ins = 1;
333 char const *next = src;
334 while (++si < n) {
335 next += elem_size;
336 // once we become larger than the list elem, break
337 if (cmp(list_elm, next) <= 0) {
338 break;
339 }
340 // otherwise, we can insert one more
341 ins++;
342 }
343
344 // insert the elements at location si
345 if (ins == 1) {
346 if (0 != invoke_list_func(insert_element,
347 list, di, src))
348 return inserted;
349 } else {
350 size_t r = invoke_list_func(insert_array, list, di, src, ins);
351 if (r < ins) return inserted + r;
352 }
353 inserted += ins;
354 di += ins;
355
356 // everything inserted?
357 if (inserted == n) return inserted;
358 src = next;
359 }
360
361 // insert remaining items
362 if (si < n) {
363 inserted += invoke_list_func(insert_array, list, di, src, n - si);
364 }
365
366 return inserted;
319 } 367 }
320 368
321 void cx_list_default_sort(struct cx_list_s *list) { 369 void cx_list_default_sort(struct cx_list_s *list) {
322 size_t elem_size = list->collection.elem_size; 370 size_t elem_size = list->collection.elem_size;
323 size_t list_size = list->collection.size; 371 size_t list_size = list->collection.size;

mercurial