In some cases the license-identification header was missing, so I added that as well. Replaced the remaining headers that specifically identified "Versions 3.13.7 and higher". Makefiles and the build system were deliberately excluded.
84 lines
2.2 KiB
C
84 lines
2.2 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2014 Brookhaven Science Assoc., as Operator of Argonne
|
|
* National Laboratory.
|
|
* Copyright (c) 2016 Michael Davidsaver
|
|
* SPDX-License-Identifier: EPICS
|
|
* EPICS BASE is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
|
|
/*
|
|
* Use of mergesort algorithm based on analysis by
|
|
* http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
|
|
*/
|
|
#include <stdlib.h>
|
|
|
|
#include "epicsAssert.h"
|
|
#include "ellLib.h"
|
|
|
|
static void ellMoveN(ELLLIST* pTo, ELLLIST* pFrom, int count )
|
|
{
|
|
for(;count && ellCount(pFrom); count--) {
|
|
ELLNODE *node = ellGet(pFrom);
|
|
ellAdd(pTo, node);
|
|
}
|
|
}
|
|
|
|
/* Stable (MergeSort) to given list.
|
|
* The comparison function cmp(A,B) is expected
|
|
* to return -1 for A<B, 0 for A==B, and 1 for A>B.
|
|
*/
|
|
void ellSortStable(ELLLIST *pList, pListCmp cmp)
|
|
{
|
|
ELLLIST INP, P, Q;
|
|
size_t insize = 1; /* initial sub-list size */
|
|
if(ellCount(pList)<=1)
|
|
return;
|
|
|
|
ellInit(&INP);
|
|
ellInit(&P);
|
|
ellInit(&Q);
|
|
|
|
/* Process is to iteratively sort
|
|
* a sequence of sub-lists of size 'insize'
|
|
*/
|
|
|
|
while(insize < ellCount(pList)) {
|
|
|
|
assert(ellCount(&INP)==0);
|
|
|
|
/* shift previous results to inputs */
|
|
ellConcat(&INP, pList);
|
|
|
|
while(ellCount(&INP))
|
|
{
|
|
ELLNODE *p, *q;
|
|
|
|
/* Pull out the next pair of sub-lists */
|
|
ellMoveN(&Q, &INP, insize);
|
|
ellMoveN(&P, &INP, insize);
|
|
|
|
/* merge these sub-lists */
|
|
while((p=ellFirst(&P)) && (q=ellFirst(&Q)))
|
|
{
|
|
if((*cmp)(p,q) < 0) {
|
|
ellAdd(pList, ellGet(&P));
|
|
} else {
|
|
ellAdd(pList, ellGet(&Q));
|
|
}
|
|
}
|
|
|
|
/* concatenate any remaining to result */
|
|
if(ellFirst(&P))
|
|
ellConcat(pList, &P);
|
|
else if(ellFirst(&Q))
|
|
ellConcat(pList, &Q);
|
|
|
|
assert(!ellFirst(&P) && !ellFirst(&Q));
|
|
}
|
|
|
|
insize *= 2;
|
|
}
|
|
|
|
}
|