/**************************** support.c ********************************** Purpose: Provide some useful support routines: -- Storage allocators that exit on error (since this isn't a subroutine library, there's no need for fancy error-handling). -- A routine to write the MPHF to a file. -- A routine to verify the correctness of a MPHF. Provenance: Written and tested by Q. Chen and E. Fox, March 1991. Edited and tested by S. Wartik, April 1991. Notes: None. **/ #include #include "types.h" #ifdef __STDC__ extern char *malloc( unsigned int size ); extern char *realloc ( char *area, unsigned int size ); extern void exit(); #else extern char *malloc(), *realloc(); extern void exit(); #endif /************************************************************************* owncalloc( n, size ) Return: char * -- Pointer to a chunk of memory. Purpose: Allocate a chunk of memory of 'n' elements each of size 'size'. Return the pointer to the chunk. Abort if no space is available. **/ char *owncalloc( n, size ) int n, /* in: number of elements. */ size; /* in: size of each element. */ { char *temp; if ( (temp = malloc( (unsigned int)(n*size) )) == 0 ) { fputs("Panic: cannot allocate memory.\n", stderr); exit(1); } return(temp); } /************************************************************************* ownrealloc( n, size ) Return: char * -- Pointer to a chunk of memory. Purpose: Re-allocate a chunk of memory pointed to by area -- make it new_size bytes. Abort if no space is available. **/ char *ownrealloc( area, new_size ) char *area; /* in: area to re-allocate. */ int new_size; /* in: new size. */ { char *temp; if ( (temp = realloc( area, (unsigned)new_size )) == 0 ) { fputs("Panic: cannot reallocate memory.\n", stderr); exit(1); } return(temp); } /************************************************************************* write_gfun( arcs, vertices, tbl_seed, spec_file ) Return: void Purpose: Write the MPHF specification to a file **/ void write_gfun( arcs, vertices, tbl_seed, spec_file ) arcsType *arcs; /* in: the arcs. */ verticesType *vertices; /* in: the vertices. */ int tbl_seed; /* in: seed used to set up random number tables. */ char *spec_file; /* in: name of the specification file. */ { int i; /* Iterator through vertices. */ FILE *fp; /* Handle for specification file. */ if ( (fp = fopen(spec_file, "w")) == NULL ) { fprintf(stderr, "Can't create hashing specification file \"%s\".\n", spec_file); exit(1); } fprintf(fp, "%d\n%d\n%d\n", arcs->no_arcs, vertices->no_vertices, tbl_seed); for ( i = 0; i < vertices->no_vertices; i++ ) fprintf(fp, "%d\n", vertices->vertexArray[i].g); fclose(fp); } /************************************************************************* verify_mphf( arcs, vertices ) Return: int -- NORM if MPHF is correct, ABNORM if not. Purpose: Verify the computed MPHF is indeed minimal and perfect **/ int verify_mphf( arcs, vertices ) arcsType *arcs; /* in: the arcs. */ verticesType *vertices; /* in: the vertices. */ { int i, status = NORM, hash; /* Hash value of a key. */ char *disk; /* Hash table. */ disk = owncalloc( arcs->no_arcs, sizeof(char) ); for( i = 0; i < arcs->no_arcs; disk[i++] = EMPTY ); for ( i = 0; i < arcs->no_arcs; i++ ) { hash = abs( arcs->arcArray[i].h0 + vertices->vertexArray[arcs->arcArray[i].h12[0]].g + vertices->vertexArray[arcs->arcArray[i].h12[1]].g ) % arcs->no_arcs ; if ( hash < 0 ) { fprintf(stderr, "Panic: negative hash value.\n"); status = ABNORM; break; } if ( disk[hash] == FULL ) { fprintf(stderr, "Panic: hash entry collided at"); fprintf(stderr, " position %d by the %dth word!\n", hash, i); status = ABNORM; break; } else disk[hash] = FULL; } free( (char *)disk ); return(status); }