/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 2003-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#include "vchdr.h"
#include "vgraph.h"
/* Algorithm to compute the suffix array of a string.
** Sadakane-Larson magic numbering is used to speed up sort.
** Optimum branching is used to determine an optimal order
** for sorting groups with same first byte.
** The multikey-sort function detects periodic sequences and
** copy-sort them via a generalized Seward pointer-copy.
** Seward pointer-copy is also used to spread sort order.
**
** Written by Kiem-Phong Vo (kpv@research.att.com)
*/
#ifdef ITOH_TANAKA
#endif
#if !has_algorithm
#endif
#define MEDIAN(x,y,z) ((x) <= (y) ? ((y) <= (z) ? (y) : (z) >= (x) ? (z) : (x)) : \
((y) >= (z) ? (y) : (z) <= (x) ? (z) : (x)) )
#ifdef DEBUG
extern char* getenv(const char*);
if(Dblev < 0)
}
return 0;
if(Dblev == 0) /* no checking*/
return 0;
return 1; /* always checking */
}
}
return 1;
return 0;
for(i = 1; i < k; ++i) /* check distinctness */
for(k = i; k <= endi; ++k)
}
return 1;
}
Vcsfxint_t v, n, k;
for(n = p < s ? p : s, k = 0; k < n; ++k)
continue;
return v > 0 ? 1 : -1;
}
return p < s ? 1 : -1;
}
return 1;
return 1;
}
#endif /*DEBUG*/
/* bucket sort by first two bytes. */
#if __STD_C
#else
#endif
{
int i, j, v;
Vcsfxint_t n, *g;
for(n = 0, g = grp, i = 0; i < 256; ++i)
{ for(j = 0; j < 256; ++j, ++g)
*g = (n += *g); /* next area to be allocated */
if(i == *ends) /* sort the last suffix now */
}
}
{ v = (i << 8) + (j = *++s);
}
{ v = (i << 8) + (j = *++s);
}
}
#if __STD_C /* swap two adjacent lists of integers */
#else
#endif
{
Vcsfxint_t m, n;
n = m;
}
#if __STD_C /* multikey-quicksort */
#else
int period; /* != 0, check periods */
#endif
{
{ pi = *l;
for(r = l-1; r >= min; --r)
if(k > 0)
break;
*(r+1) = *r;
}
*(r+1) = pi;
}
return;
}
else /* approximating a median-of-9 as a pivot */
{ for(k = 0; k < 3; ++k)
}
}
{ for(; l <= r; ++l)
break;
else if(k == 0 && (le += 1) < l)
}
for(; r >= l; --r)
break;
else if(k == 0 && (re -= 1) > r)
}
if(l < r)
l += 1; r -= 1;
}
}
else if(mn > 1)
mn = 0; /* completely sorted */
}
}
}
else if(rn > 1)
}
if(mn > 1)
}
else /* tail recursion to save stack space */
goto q_sort;
}
}
}
#if __STD_C /* copy-sort yx-groups based on the sort order of x-suffixes */
#else
Vcsfxint_t y; /* common first byte */
#endif
{
/* bounds of group headed by the same y */
return;
/* set boundary of groups to be copy-sorted */
for(k = 0, x = 0; x < 256; ++x)
k += 1; /* nontrivial sortable group */
else if(x != y) /* already sorted */
l = r = -1;
else if(l > r) /* empty yy-group */
/*else; non-empty yy-group, run both loops below */
}
if(k == 0) /* nothing to do */
return;
}
#if __STD_C /* sort the unsorted xy-groups for the same x */
#else
Vcsfxint_t x; /* common header byte */
int dir; /* itoh-tanaka sort dir */
#endif
{
Vcsfxint_t l, r, k, i, y, z;
Gredge_t *e;
/* construct graph of relations between xy-groups */
goto done;
for(y = 0; y < 256; ++y)
continue;
continue; /* single or xx-group */
continue; /* already sorted */
goto done;
for(k = 0; k < 3; ++k)
continue;
continue;
goto done;
}
}
if((k = grbranching(gr)) < 0)
goto done;
/* now sort xy-groups in their top-sort order */
{ if(!hd)
}
}
}
rv = 0; /* successful processing */
return rv;
}
#if __STD_C
#else
#endif
{
return sfx;
}
#ifdef ITOH_TANAKA /* sfxqsort half the data using itoh-tanaka strategy */
{ Vcsfxint_t c, d;
c = d = 0;
for(x = 0; x < 256; ++x)
for(y = 0; y < 256; ++y)
continue;
if(x < y)
c += r-l+1;
else d += r-l+1;
}
d = c <= d ? 1 : -1; /* sort direction */
for(x = d > 0 ? 0 : 255; x >= 0 && x <= 255; x += d)
continue;
goto it_err;
}
error = 0; /* have done well */
it_err: ;
}
#endif
#ifdef OPT_BRANCHING
{ /* use an optimum branching to determine sort order of x-groups */
Gredge_t *e;
goto ob_err;
for(x = 0; x < 256; ++x)
continue;
goto ob_err;
for(y = 0; y < 256; ++y)
continue;
goto ob_err;
grbrweight(e, r-l+1);
}
}
if((r = grbranching(gr)) < 0)
{ if(!hd)
}
goto ob_err;
}
error = 0; /* have done well */
}
#endif
if(error)
}
return sfx;
}