2
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
12
* The above copyright notice including the dates of first publication and
13
* either this permission notice or a reference to
14
* http://oss.sgi.com/projects/FreeB/
15
* shall be included in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
* Except as contained in this notice, the name of Silicon Graphics, Inc.
26
* shall not be used in advertising or otherwise to promote the sale, use or
27
* other dealings in this Software without prior written authorization from
28
* Silicon Graphics, Inc.
31
** Author: Eric Veach, July 1994.
37
#include <limits.h> /* LONG_MAX */
40
/* Include all the code for the regular heap-based queue here. */
42
#include "priorityq-heap.i"
44
/* Now redefine all the function names to map to their "Sort" versions. */
46
#include "priorityq-sort.h"
48
/* really __gl_pqSortNewPriorityQ */
49
PriorityQ* pqNewPriorityQ(int (*leq)(PQkey key1, PQkey key2))
51
PriorityQ* pq=(PriorityQ*)memAlloc(sizeof(PriorityQ));
57
pq->heap=__gl_pqHeapNewPriorityQ(leq);
64
pq->keys=(PQHeapKey*)memAlloc(INIT_SIZE*sizeof(pq->keys[0]));
67
__gl_pqHeapDeletePriorityQ(pq->heap);
74
pq->initialized=FALSE;
80
/* really __gl_pqSortDeletePriorityQ */
81
void pqDeletePriorityQ(PriorityQ* pq)
86
__gl_pqHeapDeletePriorityQ(pq->heap);
99
#define LT(x,y) (!LEQ(y,x))
100
#define GT(x,y) (!LEQ(x,y))
101
#define Swap(a, b) if(1) { PQkey* tmp=*a; *a=*b; *b=tmp; } else {;}
103
/* really __gl_pqSortInit */
104
int pqInit(PriorityQ* pq)
106
PQkey**p, **r, **i, **j, *piv;
111
} Stack[50], *top=Stack;
112
unsigned long seed=2016473283;
114
/* Create an array of indirect pointers to the keys, so that we
115
* the handles we have returned are still valid.
118
pq->order = (PQHeapKey **)memAlloc( (size_t)
119
(pq->size * sizeof(pq->order[0])) );
121
pq->order=(PQHeapKey**)memAlloc((size_t)((pq->size+1)*sizeof(pq->order[0])));
122
/* the previous line is a patch to compensate for the fact that IBM */
123
/* machines return a null on a malloc of zero bytes (unlike SGI), */
124
/* so we have to put in this defense to guard against a memory */
125
/* fault four lines down. from fossum@austin.ibm.com. */
133
for (piv=pq->keys, i=p; i<=r; ++piv, ++i)
138
/* Sort the indirect pointers in descending order,
139
* using randomized Quicksort
141
top->p=p; top->r=r; ++top;
148
seed=seed*1539415821+1;
158
} while(GT(**i, *piv));
161
} while(LT(**j, *piv));
164
Swap(i, j); /* Undo last swap */
181
/* Insertion sort small lists */
182
for (i=p+1; i<=r; ++i)
185
for (j=i; j>p && LT(**(j-1), *piv); --j)
194
pq->initialized=TRUE;
195
__gl_pqHeapInit(pq->heap); /* always succeeds */
203
assert(LEQ(**(i+1), **i));
210
/* really __gl_pqSortInsert */
211
/* returns LONG_MAX iff out of memory */
212
PQhandle pqInsert(PriorityQ* pq, PQkey keyNew)
218
return __gl_pqHeapInsert(pq->heap, keyNew);
222
if (++pq->size>=pq->max)
224
PQkey* saveKey=pq->keys;
226
/* If the heap overflows, double its size. */
228
pq->keys=(PQHeapKey*)memRealloc(pq->keys, (size_t)(pq->max*sizeof(pq->keys[0])));
231
/* restore ptr to free upon return */
236
assert(curr!=LONG_MAX);
237
pq->keys[curr]=keyNew;
239
/* Negative handles index the sorted array. */
243
/* really __gl_pqSortExtractMin */
244
PQkey pqExtractMin(PriorityQ* pq)
246
PQkey sortMin, heapMin;
250
return __gl_pqHeapExtractMin(pq->heap);
253
sortMin=*(pq->order[pq->size-1]);
254
if (!__gl_pqHeapIsEmpty(pq->heap))
256
heapMin=__gl_pqHeapMinimum(pq->heap);
257
if (LEQ(heapMin, sortMin))
259
return __gl_pqHeapExtractMin(pq->heap);
264
} while(pq->size>0 && *(pq->order[pq->size-1])==NULL);
269
/* really __gl_pqSortMinimum */
270
PQkey pqMinimum(PriorityQ* pq)
272
PQkey sortMin, heapMin;
276
return __gl_pqHeapMinimum(pq->heap);
279
sortMin=*(pq->order[pq->size-1]);
280
if (!__gl_pqHeapIsEmpty(pq->heap))
282
heapMin=__gl_pqHeapMinimum(pq->heap);
283
if (LEQ(heapMin, sortMin))
292
/* really __gl_pqSortIsEmpty */
293
int pqIsEmpty(PriorityQ* pq)
295
return (pq->size==0) && __gl_pqHeapIsEmpty(pq->heap);
298
/* really __gl_pqSortDelete */
299
void pqDelete(PriorityQ* pq, PQhandle curr)
303
__gl_pqHeapDelete(pq->heap, curr);
308
assert(curr<pq->max && pq->keys[curr]!=NULL);
312
while(pq->size>0 && *(pq->order[pq->size-1])==NULL)