rsinha@cs.rmit.edu.au
namespace sinha_burstsortA {
static const int THRESHOLD = 8192;
static const int THRESHOLDMINUSONE = (THRESHOLD - 1);
static const int LEVEL = 7;
static const int ALPHABET = 256;
static const int INSERTBREAK = 20;
typedef unsigned char* string;
inline void EXIT() {
exit(EXIT_FAILURE);
}
inline void ERR_PRINT_OUT_OF_MEMORY() {
printf("Error: Out of memory \n");
}
typedef struct trierec
{
char **nulltailptr;
unsigned char levels[ALPHABET];
int counts[ALPHABET];
char **ptrs[ALPHABET];
} TRIE;
static unsigned short bucket_inc[LEVEL] = {0, 16, 128, 1024, 8192, 16384, 32768};
static void
burstinsertA(TRIE *root, string strings[], int scnt)
{
TRIE *new_;
TRIE *curr;
int i, j;
int newcounts, currcounts;
unsigned char c, cc=0, p;
for( i=0 ; i<scnt ; i++ )
{
curr = root;
for( p = 0, c = strings[i][p]; curr->counts[c] < 0; curr = (TRIE *) curr->ptrs[c], p++, c = strings[i][p])
;
if(curr->counts[c] < 1)
{
if (c == 0)
{
if ((curr->ptrs[c] = (char **) calloc(THRESHOLD, sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
curr->nulltailptr = curr->ptrs[c];
*curr->nulltailptr = (char *) strings[i];
curr->nulltailptr++;
curr->counts[c]++;
}
else
{
if ((curr->ptrs[c] = (char **) calloc(bucket_inc[1], sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
curr->ptrs[c][curr->counts[c]++] = (char *) strings[i];
curr->levels[c]++;
}
}
else
{
if (c == 0)
{
*curr->nulltailptr = (char *) strings[i];
curr->nulltailptr++;
curr->counts[c]++;
if ( (curr->counts[c] % THRESHOLDMINUSONE) == 0)
{
if ((*curr->nulltailptr = (char *) calloc(THRESHOLD, sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
else
curr->nulltailptr = (char **) *curr->nulltailptr;
}
}
else
{
curr->ptrs[c][curr->counts[c]++] = (char *) strings[i];
currcounts = curr->counts[c];
if (currcounts < THRESHOLD && currcounts > (bucket_inc[curr->levels[c]] - 1) )
if((curr->ptrs[c] = (char **) realloc(curr->ptrs[c], bucket_inc[++curr->levels[c]] * sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
}
while ( curr->counts[c] >= THRESHOLD && c != 0 )
{
p++;
if ((new_ = (TRIE *) calloc(1, sizeof(TRIE))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
currcounts = curr->counts[c];
for(j=0; j < currcounts; j++)
{
cc = curr->ptrs[c][j][p];
if(new_->counts[cc] < 1)
{
if (cc == 0)
{
if ((new_->ptrs[cc] = (char **) calloc(THRESHOLD, sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
new_->nulltailptr = new_->ptrs[cc];
*new_->nulltailptr = (char *) curr->ptrs[c][j];
new_->nulltailptr++;
new_->counts[cc]++;
}
else
{
if ((new_->ptrs[cc] = (char **) calloc(bucket_inc[1], sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
new_->ptrs[cc][new_->counts[cc]++] = (char *) curr->ptrs[c][j];
new_->levels[cc]++;
}
}
else
{
if (cc == 0)
{
*new_->nulltailptr = (char *) curr->ptrs[c][j];
new_->nulltailptr++;
new_->counts[cc]++;
if ( (new_->counts[cc] % THRESHOLDMINUSONE) == 0)
{
if ((*new_->nulltailptr = (char *) calloc(THRESHOLD, sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
else
new_->nulltailptr = (char **) *new_->nulltailptr;
}
}
else
{
new_->ptrs[cc][new_->counts[cc]++] = (char *) curr->ptrs[c][j];
newcounts = new_->counts[cc];
if (newcounts < THRESHOLD && newcounts > (bucket_inc[new_->levels[cc]] - 1) )
if((new_->ptrs[cc] = (char **) realloc(new_->ptrs[cc], bucket_inc[++new_->levels[cc]] * sizeof(char *))) == NULL)
{
ERR_PRINT_OUT_OF_MEMORY();
EXIT();
}
}
}
}
free(curr->ptrs[c]);
curr->ptrs[c] = (char **) new_;
curr->counts[c] = -1;
curr = new_;
c = cc;
}
}
}
}
static int
bursttraverseA(TRIE *node, string strings[], int pos, unsigned short deep)
{
int i, j, k;
int off = 0;
unsigned short no_of_buckets=0, no_elements_in_last_bucket=0, no_elements_in_bucket=0;
char **nullbucket, **headbucket;
int count;
for( i=0 ; i < ALPHABET; i++)
{
count = node->counts[i];
if( !++count )
{
pos = bursttraverseA((TRIE *) node->ptrs[i], strings, pos, deep+1);
}
else if (--count)
{
if(i==0)
{
no_of_buckets = (count/THRESHOLDMINUSONE) + 1;
no_elements_in_last_bucket = count % THRESHOLDMINUSONE;
nullbucket = node->ptrs[i];
headbucket = node->ptrs[i];
off=pos;
for (k=1; k <= no_of_buckets; k++)
{
if(k==no_of_buckets)
no_elements_in_bucket = no_elements_in_last_bucket;
else
no_elements_in_bucket = THRESHOLDMINUSONE;
for (j=0; j < no_elements_in_bucket ; j++, off++)
{
strings[off] = (unsigned char*) nullbucket[j];
}
nullbucket = (char **) nullbucket[j];
free(headbucket);
headbucket = nullbucket;
}
}
else
{
for( j=0, off=pos ; j < count ; j++, off++)
strings[off] = (unsigned char*) node->ptrs[i][j];
free( node->ptrs[i] );
if (count > 1)
{
if (count < INSERTBREAK)
inssort::inssort( strings+pos, off-pos, deep + 1);
else
bs_mkqs::ssort2( strings+pos, off-pos, deep + 1);
}
}
pos = off;
}
}
free(node);
return pos;
}
void
burstsortA(string strings[], size_t scnt)
{
TRIE *root;
root = (TRIE *) calloc(1, sizeof(TRIE));
burstinsertA(root, strings, scnt);
bursttraverseA(root, strings, 0, 0);
return;
}
CONTESTANT_REGISTER(burstsortA,
"sinha/burstsortA",
"burstsortA Original Burstsort with arrays")
}