|
Lines 529-574
list_flush (List l)
Link Here
|
| 529 |
return(n); |
529 |
return(n); |
| 530 |
} |
530 |
} |
| 531 |
|
531 |
|
| 532 |
|
|
|
| 533 |
void |
532 |
void |
| 534 |
list_sort (List l, ListCmpF f) |
533 |
list_sort (List l, ListCmpF f) |
| 535 |
{ |
534 |
{ |
| 536 |
/* Note: Time complexity O(n^2). |
|
|
| 537 |
*/ |
| 538 |
ListNode *pp, *ppPrev, *ppPos, pTmp; |
535 |
ListNode *pp, *ppPrev, *ppPos, pTmp; |
| 539 |
ListIterator i; |
536 |
ListIterator it; |
|
|
537 |
|
| 538 |
ListNode p, q, e, tail, head; |
| 539 |
int insize, nmerges, psize, qsize, i; |
| 540 |
|
540 |
|
| 541 |
assert(l != NULL); |
541 |
assert(l != NULL); |
| 542 |
assert(f != NULL); |
542 |
assert(f != NULL); |
| 543 |
list_mutex_lock(&l->mutex); |
543 |
list_mutex_lock(&l->mutex); |
| 544 |
assert(l->magic == LIST_MAGIC); |
544 |
assert(l->magic == LIST_MAGIC); |
|
|
545 |
head = l->head; |
| 545 |
if (l->count > 1) { |
546 |
if (l->count > 1) { |
| 546 |
ppPrev = &l->head; |
547 |
insize=1; |
| 547 |
pp = &(*ppPrev)->next; |
548 |
while(1) { |
| 548 |
while (*pp) { |
549 |
p = head; |
| 549 |
if (f((*pp)->data, (*ppPrev)->data) < 0) { |
550 |
head = NULL; |
| 550 |
ppPos = &l->head; |
551 |
tail = NULL; |
| 551 |
while (f((*pp)->data, (*ppPos)->data) >= 0) |
552 |
|
| 552 |
ppPos = &(*ppPos)->next; |
553 |
|
| 553 |
pTmp = (*pp)->next; |
554 |
nmerges = 0; |
| 554 |
(*pp)->next = *ppPos; |
555 |
while(p) { |
| 555 |
*ppPos = *pp; |
556 |
nmerges++; |
| 556 |
*pp = pTmp; |
557 |
q = p; |
| 557 |
if (ppPrev == ppPos) |
558 |
|
| 558 |
ppPrev = &(*ppPrev)->next; |
559 |
psize=0; |
| 559 |
} |
560 |
for (i = 0; i < insize; i++) { |
| 560 |
else { |
561 |
psize++; |
| 561 |
ppPrev = pp; |
562 |
q = q->next; |
| 562 |
pp = &(*pp)->next; |
563 |
|
| 563 |
} |
564 |
if (!q) break; |
| 564 |
} |
565 |
} |
| 565 |
l->tail = pp; |
566 |
qsize = insize; |
| 566 |
|
567 |
while (psize > 0 || (qsize > 0 && q)) { |
| 567 |
for (i=l->iNext; i; i=i->iNext) { |
568 |
if (psize == 0) { |
| 568 |
assert(i->magic == LIST_MAGIC); |
569 |
e = q; |
| 569 |
i->pos = i->list->head; |
570 |
q = q->next; |
| 570 |
i->prev = &i->list->head; |
571 |
qsize--; |
| 571 |
} |
572 |
} else if (qsize == 0 || !q ) { |
|
|
573 |
e = p; |
| 574 |
p = p->next; |
| 575 |
psize--; |
| 576 |
} else if (f(p->data,q->data) < 0) { |
| 577 |
e = p; |
| 578 |
p = p->next; |
| 579 |
psize--; |
| 580 |
} else { |
| 581 |
e = q; |
| 582 |
q = q->next; |
| 583 |
qsize--; |
| 584 |
} |
| 585 |
if (tail) { |
| 586 |
tail->next = e; |
| 587 |
} else { |
| 588 |
head = e; |
| 589 |
} |
| 590 |
tail = e; |
| 591 |
} |
| 592 |
p = q; |
| 593 |
|
| 594 |
} |
| 595 |
tail->next = NULL; |
| 596 |
if(nmerges <= 1) { |
| 597 |
l->head = head; |
| 598 |
l->tail = &tail; |
| 599 |
for (it=l->iNext; it; it=it->iNext) { |
| 600 |
assert(it->magic == LIST_MAGIC); |
| 601 |
it->pos = it->list->head; |
| 602 |
it->prev = &it->list->head; |
| 603 |
} |
| 604 |
|
| 605 |
list_mutex_unlock(&l->mutex); |
| 606 |
return; |
| 607 |
} |
| 608 |
insize *=2; |
| 609 |
} |
| 572 |
} |
610 |
} |
| 573 |
list_mutex_unlock(&l->mutex); |
611 |
list_mutex_unlock(&l->mutex); |
| 574 |
return; |
612 |
return; |