diff options
Diffstat (limited to 'jam-files/engine/hcache.c')
-rw-r--r-- | jam-files/engine/hcache.c | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/jam-files/engine/hcache.c b/jam-files/engine/hcache.c deleted file mode 100644 index 70bb798c..00000000 --- a/jam-files/engine/hcache.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * This file has been donated to Jam. - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "rules.h" -# include "regexp.h" -# include "headers.h" -# include "newstr.h" -# include "hash.h" -# include "hcache.h" -# include "variable.h" -# include "search.h" - -#ifdef OPT_HEADER_CACHE_EXT - -/* - * Craig W. McPheeters, Alias|Wavefront. - * - * hcache.c hcache.h - handle cacheing of #includes in source files. - * - * Create a cache of files scanned for headers. When starting jam, look for the - * cache file and load it if present. When finished the binding phase, create a - * new header cache. The cache contains files, their timestamps and the header - * files found in their scan. During the binding phase of jam, look in the - * header cache first for the headers contained in a file. If the cache is - * present and valid, use its contents. This results in dramatic speedups with - * large projects (eg. 3min -> 1min startup for one project.) - * - * External routines: - * hcache_init() - read and parse the local .jamdeps file. - * hcache_done() - write a new .jamdeps file. - * hcache() - return list of headers on target. Use cache or do a scan. - * - * The dependency file format is an ASCII file with 1 line per target. Each line - * has the following fields: - * @boundname@ timestamp @file@ @file@ @file@ ... \n - */ - -typedef struct hcachedata HCACHEDATA ; - -struct hcachedata -{ - char * boundname; - time_t time; - LIST * includes; - LIST * hdrscan; /* the HDRSCAN value for this target */ - int age; /* if too old, we'll remove it from cache */ - HCACHEDATA * next; -}; - - -static struct hash * hcachehash = 0; -static HCACHEDATA * hcachelist = 0; - -static int queries = 0; -static int hits = 0; - -#define CACHE_FILE_VERSION "version 4" -#define CACHE_RECORD_HEADER "header" -#define CACHE_RECORD_END "end" - - -/* - * Return the name of the header cache file. May return NULL. - * - * The user sets this by setting the HCACHEFILE variable in a Jamfile. We cache - * the result so the user can not change the cache file during header scanning. - */ - -static char * cache_name( void ) -{ - static char * name = 0; - if ( !name ) - { - LIST * hcachevar = var_get( "HCACHEFILE" ); - - if ( hcachevar ) - { - TARGET * t = bindtarget( hcachevar->string ); - - pushsettings( t->settings ); - /* Do not expect the cache file to be generated, so pass 0 as the - * third argument to search. Expect the location to be specified via - * LOCATE, so pass 0 as the fourth arugment. - */ - t->boundname = search( t->name, &t->time, 0, 0 ); - popsettings( t->settings ); - - if ( hcachevar ) - name = copystr( t->boundname ); - } - } - return name; -} - - -/* - * Return the maximum age a cache entry can have before it is purged ftom the - * cache. - */ - -static int cache_maxage( void ) -{ - int age = 100; - LIST * var = var_get( "HCACHEMAXAGE" ); - if ( var ) - { - age = atoi( var->string ); - if ( age < 0 ) - age = 0; - } - return age; -} - - -/* - * Read a netstring. The caveat is that the string can not contain ASCII 0. The - * returned value is as returned by newstr(), so it need not be freed. - */ - -char * read_netstring( FILE * f ) -{ - unsigned long len; - static char * buf = NULL; - static unsigned long buf_len = 0; - - if ( fscanf( f, " %9lu", &len ) != 1 ) - return NULL; - if ( fgetc( f ) != (int)'\t' ) - return NULL; - - if ( len > 1024 * 64 ) - return NULL; /* sanity check */ - - if ( len > buf_len ) - { - unsigned long new_len = buf_len * 2; - if ( new_len < len ) - new_len = len; - buf = (char *)BJAM_REALLOC( buf, new_len + 1 ); - if ( buf ) - buf_len = new_len; - } - - if ( !buf ) - return NULL; - - if ( fread( buf, 1, len, f ) != len ) - return NULL; - if ( fgetc( f ) != (int)'\n' ) - return NULL; - - buf[ len ] = 0; - return newstr( buf ); -} - - -/* - * Write a netstring. - */ - -void write_netstring( FILE * f, char const * s ) -{ - if ( !s ) - s = ""; - fprintf( f, "%lu\t%s\n", (long unsigned)strlen( s ), s ); -} - - -void hcache_init() -{ - HCACHEDATA cachedata; - HCACHEDATA * c; - FILE * f; - char * version; - int header_count = 0; - char * hcachename; - - hcachehash = hashinit( sizeof( HCACHEDATA ), "hcache" ); - - if ( !( hcachename = cache_name() ) ) - return; - - if ( !( f = fopen( hcachename, "rb" ) ) ) - return; - - version = read_netstring( f ); - if ( !version || strcmp( version, CACHE_FILE_VERSION ) ) - { - fclose( f ); - return; - } - - while ( 1 ) - { - char * record_type; - char * time_str; - char * age_str; - char * includes_count_str; - char * hdrscan_count_str; - int i; - int count; - LIST * l; - - record_type = read_netstring( f ); - if ( !record_type ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - if ( !strcmp( record_type, CACHE_RECORD_END ) ) - break; - if ( strcmp( record_type, CACHE_RECORD_HEADER ) ) - { - fprintf( stderr, "invalid %s with record separator <%s>\n", - hcachename, record_type ? record_type : "<null>" ); - goto bail; - } - - c = &cachedata; - - c->boundname = read_netstring( f ); - time_str = read_netstring( f ); - age_str = read_netstring( f ); - includes_count_str = read_netstring( f ); - - if ( !c->boundname || !time_str || !age_str || !includes_count_str ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - - c->time = atoi( time_str ); - c->age = atoi( age_str ) + 1; - - count = atoi( includes_count_str ); - for ( l = 0, i = 0; i < count; ++i ) - { - char * s = read_netstring( f ); - if ( !s ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - l = list_new( l, s ); - } - c->includes = l; - - hdrscan_count_str = read_netstring( f ); - if ( !includes_count_str ) - { - list_free( c->includes ); - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - - count = atoi( hdrscan_count_str ); - for ( l = 0, i = 0; i < count; ++i ) - { - char * s = read_netstring( f ); - if ( !s ) - { - fprintf( stderr, "invalid %s\n", hcachename ); - goto bail; - } - l = list_new( l, s ); - } - c->hdrscan = l; - - if ( !hashenter( hcachehash, (HASHDATA * *)&c ) ) - { - fprintf( stderr, "can't insert header cache item, bailing on %s\n", - hcachename ); - goto bail; - } - - c->next = hcachelist; - hcachelist = c; - - ++header_count; - } - - if ( DEBUG_HEADER ) - printf( "hcache read from file %s\n", hcachename ); - - bail: - fclose( f ); -} - - -void hcache_done() -{ - FILE * f; - HCACHEDATA * c; - int header_count = 0; - char * hcachename; - int maxage; - - if ( !hcachehash ) - return; - - if ( !( hcachename = cache_name() ) ) - return; - - if ( !( f = fopen( hcachename, "wb" ) ) ) - return; - - maxage = cache_maxage(); - - /* Print out the version. */ - write_netstring( f, CACHE_FILE_VERSION ); - - c = hcachelist; - for ( c = hcachelist; c; c = c->next ) - { - LIST * l; - char time_str[ 30 ]; - char age_str[ 30 ]; - char includes_count_str[ 30 ]; - char hdrscan_count_str[ 30 ]; - - if ( maxage == 0 ) - c->age = 0; - else if ( c->age > maxage ) - continue; - - sprintf( includes_count_str, "%lu", (long unsigned) list_length( c->includes ) ); - sprintf( hdrscan_count_str, "%lu", (long unsigned) list_length( c->hdrscan ) ); - sprintf( time_str, "%lu", (long unsigned) c->time ); - sprintf( age_str, "%lu", (long unsigned) c->age ); - - write_netstring( f, CACHE_RECORD_HEADER ); - write_netstring( f, c->boundname ); - write_netstring( f, time_str ); - write_netstring( f, age_str ); - write_netstring( f, includes_count_str ); - for ( l = c->includes; l; l = list_next( l ) ) - write_netstring( f, l->string ); - write_netstring( f, hdrscan_count_str ); - for ( l = c->hdrscan; l; l = list_next( l ) ) - write_netstring( f, l->string ); - fputs( "\n", f ); - ++header_count; - } - write_netstring( f, CACHE_RECORD_END ); - - if ( DEBUG_HEADER ) - printf( "hcache written to %s. %d dependencies, %.0f%% hit rate\n", - hcachename, header_count, queries ? 100.0 * hits / queries : 0 ); - - fclose ( f ); -} - - -LIST * hcache( TARGET * t, int rec, regexp * re[], LIST * hdrscan ) -{ - HCACHEDATA cachedata; - HCACHEDATA * c = &cachedata; - - LIST * l = 0; - - ++queries; - - c->boundname = t->boundname; - - if (hashcheck (hcachehash, (HASHDATA **) &c)) - { - if (c->time == t->time) - { - LIST *l1 = hdrscan, *l2 = c->hdrscan; - while (l1 && l2) { - if (l1->string != l2->string) { - l1 = NULL; - } else { - l1 = list_next(l1); - l2 = list_next(l2); - } - } - if (l1 || l2) { - if (DEBUG_HEADER) - printf("HDRSCAN out of date in cache for %s\n", - t->boundname); - - printf("HDRSCAN out of date for %s\n", t->boundname); - printf(" real : "); - list_print(hdrscan); - printf("\n cached: "); - list_print(c->hdrscan); - printf("\n"); - - list_free(c->includes); - list_free(c->hdrscan); - c->includes = 0; - c->hdrscan = 0; - } else { - if (DEBUG_HEADER) - printf ("using header cache for %s\n", t->boundname); - c->age = 0; - ++hits; - l = list_copy (0, c->includes); - return l; - } - } else { - if (DEBUG_HEADER) - printf ("header cache out of date for %s\n", t->boundname); - list_free (c->includes); - list_free(c->hdrscan); - c->includes = 0; - c->hdrscan = 0; - } - } else { - if (hashenter (hcachehash, (HASHDATA **)&c)) { - c->boundname = newstr (c->boundname); - c->next = hcachelist; - hcachelist = c; - } - } - - /* 'c' points at the cache entry. Its out of date. */ - - l = headers1 (0, t->boundname, rec, re); - - c->time = t->time; - c->age = 0; - c->includes = list_copy (0, l); - c->hdrscan = list_copy(0, hdrscan); - - return l; -} - -#endif |