Dont cache directorys until theyve been scanned. Avoids losing subdir

contents. Also fixed cache hashing function (was returning constant).
    Lots of comments
This commit is contained in:
Keith Packard 2003-02-12 18:19:33 +00:00
parent d2b5cc7e12
commit c8d5753c0f
2 changed files with 41 additions and 8 deletions

View File

@ -295,14 +295,14 @@ FcCacheFontSetAdd (FcFontSet *set,
} }
static unsigned int static unsigned int
FcCacheHash (const FcChar8 *string) FcCacheHash (const FcChar8 *string, int len)
{ {
unsigned int h = 0; unsigned int h = 0;
FcChar8 c; FcChar8 c;
while ((c = *string++)) while (len-- && (c = *string++))
h = (h << 1) ^ c; h = (h << 1) ^ c;
return 0; return h;
} }
/* /*
@ -376,7 +376,7 @@ FcFilePathInfoGet (const FcChar8 *path)
i.dir_len = 1; i.dir_len = 1;
i.base = path; i.base = path;
} }
i.base_hash = FcCacheHash (i.base); i.base_hash = FcCacheHash (i.base, -1);
return i; return i;
} }
@ -386,7 +386,7 @@ FcGlobalCacheDirGet (FcGlobalCache *cache,
int len, int len,
FcBool create_missing) FcBool create_missing)
{ {
unsigned int hash = FcCacheHash (dir); unsigned int hash = FcCacheHash (dir, len);
FcGlobalCacheDir *d, **prev; FcGlobalCacheDir *d, **prev;
for (prev = &cache->ents[hash % FC_GLOBAL_CACHE_DIR_HASH_SIZE]; for (prev = &cache->ents[hash % FC_GLOBAL_CACHE_DIR_HASH_SIZE];
@ -484,6 +484,11 @@ FcGlobalCacheDirDestroy (FcGlobalCacheDir *d)
free (d); free (d);
} }
/*
* Check to see if the global cache contains valid data for 'dir'.
* If so, scan the global cache for files and directories in 'dir'.
* else, return False.
*/
FcBool FcBool
FcGlobalCacheScanDir (FcFontSet *set, FcGlobalCacheScanDir (FcFontSet *set,
FcStrSet *dirs, FcStrSet *dirs,
@ -497,6 +502,7 @@ FcGlobalCacheScanDir (FcFontSet *set,
int h; int h;
int dir_len; int dir_len;
FcGlobalCacheSubdir *subdir; FcGlobalCacheSubdir *subdir;
FcBool any_in_cache = FcFalse;
if (FcDebug() & FC_DBG_CACHE) if (FcDebug() & FC_DBG_CACHE)
printf ("FcGlobalCacheScanDir %s\n", dir); printf ("FcGlobalCacheScanDir %s\n", dir);
@ -508,6 +514,10 @@ FcGlobalCacheScanDir (FcFontSet *set,
return FcFalse; return FcFalse;
} }
/*
* See if the timestamp recorded in the global cache
* matches the directory time, if not, return False
*/
if (!FcGlobalCacheCheckTime (&d->info)) if (!FcGlobalCacheCheckTime (&d->info))
{ {
if (FcDebug () & FC_DBG_CACHE) if (FcDebug () & FC_DBG_CACHE)
@ -515,12 +525,16 @@ FcGlobalCacheScanDir (FcFontSet *set,
return FcFalse; return FcFalse;
} }
/*
* Add files from 'dir' to the fontset
*/
dir_len = strlen ((const char *) dir); dir_len = strlen ((const char *) dir);
for (h = 0; h < FC_GLOBAL_CACHE_FILE_HASH_SIZE; h++) for (h = 0; h < FC_GLOBAL_CACHE_FILE_HASH_SIZE; h++)
for (f = d->ents[h]; f; f = f->next) for (f = d->ents[h]; f; f = f->next)
{ {
if (FcDebug() & FC_DBG_CACHEV) if (FcDebug() & FC_DBG_CACHEV)
printf ("FcGlobalCacheScanDir add file %s\n", f->info.file); printf ("FcGlobalCacheScanDir add file %s\n", f->info.file);
any_in_cache = FcTrue;
if (!FcCacheFontSetAdd (set, dirs, dir, dir_len, if (!FcCacheFontSetAdd (set, dirs, dir, dir_len,
f->info.file, f->name)) f->info.file, f->name))
{ {
@ -529,10 +543,14 @@ FcGlobalCacheScanDir (FcFontSet *set,
} }
FcGlobalCacheReferenced (cache, &f->info); FcGlobalCacheReferenced (cache, &f->info);
} }
/*
* Add directories in 'dir' to 'dirs'
*/
for (subdir = d->subdirs; subdir; subdir = subdir->next) for (subdir = d->subdirs; subdir; subdir = subdir->next)
{ {
FcFilePathInfo info = FcFilePathInfoGet (subdir->ent->info.file); FcFilePathInfo info = FcFilePathInfoGet (subdir->ent->info.file);
any_in_cache = FcTrue;
if (!FcCacheFontSetAdd (set, dirs, dir, dir_len, if (!FcCacheFontSetAdd (set, dirs, dir, dir_len,
info.base, FC_FONT_FILE_DIR)) info.base, FC_FONT_FILE_DIR))
{ {
@ -544,7 +562,15 @@ FcGlobalCacheScanDir (FcFontSet *set,
FcGlobalCacheReferenced (cache, &d->info); FcGlobalCacheReferenced (cache, &d->info);
return FcTrue; /*
* To recover from a bug in previous versions of fontconfig,
* return FcFalse if no entries in the cache were found
* for this directory. This will cause any empty directories
* to get rescanned every time fontconfig is initialized. This
* might get removed at some point when the older cache files are
* presumably fixed.
*/
return any_in_cache;
} }
/* /*

View File

@ -117,8 +117,6 @@ FcFileScan (FcFontSet *set,
{ {
isDir = FcTrue; isDir = FcTrue;
ret = FcStrSetAdd (dirs, file); ret = FcStrSetAdd (dirs, file);
if (cache && ret)
FcGlobalCacheUpdate (cache, file, 0, FC_FONT_FILE_DIR);
} }
/* /*
* Update the cache * Update the cache
@ -154,6 +152,11 @@ FcFileScan (FcFontSet *set,
#define FC_MAX_FILE_LEN 4096 #define FC_MAX_FILE_LEN 4096
/*
* Scan 'dir', adding font files to 'set' and
* subdirectories to 'dirs'
*/
FcBool FcBool
FcDirScan (FcFontSet *set, FcDirScan (FcFontSet *set,
FcStrSet *dirs, FcStrSet *dirs,
@ -212,6 +215,10 @@ FcDirScan (FcFontSet *set,
} }
free (file); free (file);
closedir (d); closedir (d);
/*
* Now that the directory has been scanned,
* add the cache entry
*/
if (ret && cache) if (ret && cache)
FcGlobalCacheUpdate (cache, dir, 0, 0); FcGlobalCacheUpdate (cache, dir, 0, 0);