/* This file Copyright 1993 by Clifford A. Adams */
/* sorder.c
*
* scan ordering
*/
#include "EXTERN.h"
#include "common.h"
#ifdef SCAN
#include "util.h"
#include "scan.h"
#include "smisc.h"
#ifdef SCAN_ART
#include "scanart.h"
#include "samisc.h"
#endif
#include "INTERN.h"
#include "sorder.h"
#ifdef UNDEF
int
s_compare(a,b)
long* a;
long* b; /* pointers to the two entries to be compared */
{
switch(s_cur_type) {
#ifdef SCAN_ART
case S_ART:
return sa_compare(*a,*b);
#endif
default:
return *a - *b;
}
}
#endif
int
s_compare(a,b)
long a;
long b; /* the two entry numbers to be compared */
{
switch(s_cur_type) {
#ifdef SCAN_ART
case S_ART:
return sa_compare(a,b);
#endif
default:
return a - b;
}
}
/* sort offset--used so that the 1-offset algorithm is clear even
* though the array is 0-offset.
*/
#define SOFF(a) ((a)-1)
/* Uses a heapsort algorithm with the heap readjustment inlined. */
void
s_sort_basic()
{
int i,n;
int t1;
int j;
n = s_ent_sort_max + 1;
if (n < 1)
return; /* nothing to sort */
for (i = n/2; i >= 1; i--) {
/* begin heap readjust */
t1 = s_ent_sort[SOFF(i)];
j = 2*i;
while (j <= n) {
if (j < n
&& s_compare(s_ent_sort[SOFF(j)],s_ent_sort[SOFF(j+1)]) < 0)
j++;
if (s_compare(t1,s_ent_sort[SOFF(j)]) > 0)
break; /* out of while loop */
else {
s_ent_sort[SOFF(j/2)] = s_ent_sort[SOFF(j)];
j = j*2;
}
} /* while */
s_ent_sort[SOFF(j/2)] = t1;
/* end heap readjust */
} /* for */
for (i = n-1; i >= 1; i--) {
t1 = s_ent_sort[SOFF(i+1)];
s_ent_sort[SOFF(i+1)] = s_ent_sort[SOFF(1)];
s_ent_sort[SOFF(1)] = t1;
/* begin heap readjust */
j = 2;
while (j <= i) {
if (j < i
&& s_compare(s_ent_sort[SOFF(j)],s_ent_sort[SOFF(j+1)]) < 0)
j++;
if (s_compare(t1,s_ent_sort[SOFF(j)]) > 0)
break; /* out of while */
else {
s_ent_sort[SOFF(j/2)] = s_ent_sort[SOFF(j)];
j = j*2;
}
} /* while */
s_ent_sort[SOFF(j/2)] = t1;
/* end heap readjust */
} /* for */
/* end of heapsort */
}
void
s_sort()
{
long i;
#ifdef UNDEF
qsort((void*)s_ent_sort,(s_ent_sort_max)+1,sizeof(long),s_compare);
#endif
s_sort_basic();
s_ent_sorted_max = s_ent_sort_max; /* whole array is now sorted */
s_order_changed = FALSE;
/* rebuild the indexes */
for (i = 0; i <= s_ent_sort_max; i++)
s_ent_index[s_ent_sort[i]] = i;
}
void
s_order_clean()
{
if (s_ent_sort)
free(s_ent_sort);
if (s_ent_index)
free(s_ent_index);
s_ent_sort = NULL;
s_contexts[s_cur_context].ent_sort = s_ent_sort;
s_ent_index = (long*)0;
s_contexts[s_cur_context].ent_index = s_ent_index;
s_ent_sort_max = -1;
s_ent_sorted_max = -1;
s_ent_index_max = -1;
}
/* adds the entry number to the current context */
void
s_order_add(ent)
long ent;
{
long size;
if (ent < s_ent_index_max && s_ent_index[ent] >= 0)
return; /* entry is already in the list */
/* add entry to end of sorted list */
s_ent_sort_max += 1;
if (s_ent_sort_max % 100 == 0) { /* be nice to realloc */
size = (s_ent_sort_max+100) * sizeof (long);
s_ent_sort = (long*)saferealloc((char*)s_ent_sort,size);
/* change the context too */
s_contexts[s_cur_context].ent_sort = s_ent_sort;
}
s_ent_sort[s_ent_sort_max] = ent;
/* grow index list if needed */
if (ent > s_ent_index_max) {
long old,i;
old = s_ent_index_max;
if (s_ent_index_max == -1)
s_ent_index_max += 1;
s_ent_index_max = (ent/100+1) * 100; /* round up */
size = (s_ent_index_max + 1) * sizeof (long);
s_ent_index = (long*)saferealloc((char*)s_ent_index,size);
/* change the context too */
s_contexts[s_cur_context].ent_index = s_ent_index;
/* initialize new indexes */
for (i = old+1; i < s_ent_index_max; i++)
s_ent_index[i] = -1; /* -1 == not a legal entry */
}
s_ent_index[ent] = s_ent_sort_max;
s_order_changed = TRUE;
}
long
s_prev(ent)
long ent;
{
long tmp;
if (ent < 0 || ent > s_ent_index_max || s_ent_sorted_max < 0)
return 0;
if (s_order_changed)
s_sort();
tmp = s_ent_index[ent];
if (tmp <= 0)
return 0;
return s_ent_sort[tmp-1];
}
long
s_next(ent)
long ent;
{
long tmp;
if (ent < 0 || ent > s_ent_index_max || s_ent_sorted_max < 0)
return 0;
if (s_order_changed)
s_sort();
tmp = s_ent_index[ent];
if (tmp < 0 || tmp == s_ent_sorted_max)
return 0;
return s_ent_sort[tmp+1];
}
/* given an entry, returns previous eligible entry */
/* returns 0 if no previous eligible entry */
long
s_prev_elig(a)
long a;
{
while ((a = s_prev(a)) != 0)
if (s_eligible(a))
return a;
return 0L;
}
/* given an entry, returns next eligible entry */
/* returns 0 if no next eligible entry */
long
s_next_elig(a)
long a;
{
while ((a = s_next(a)) != 0)
if (s_eligible(a))
return a;
return 0L;
}
long
s_first()
{
if (s_order_changed)
s_sort();
if (s_ent_sorted_max < 0)
return 0;
return s_ent_sort[0];
}
long
s_last()
{
if (s_order_changed)
s_sort();
if (s_ent_sorted_max < 0)
return 0;
return s_ent_sort[s_ent_sorted_max];
}
#endif /* SCAN */
syntax highlighted by Code2HTML, v. 0.9.1