From 7a6622f25cdfab5ab775324bef1833b67109801b Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Thu, 5 Dec 2013 19:15:47 +0900 Subject: [PATCH] Improve the performance issue on rescanning directories --- fc-cache/fc-cache.c | 10 ++++++++-- fontconfig/fontconfig.h | 3 +++ src/fccache.c | 13 +++++++++++++ src/fcdir.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/fcfs.c | 22 ++++++++++++++++++++++ src/fcint.h | 6 ++++++ src/fcpat.c | 2 ++ 7 files changed, 99 insertions(+), 3 deletions(-) diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c index bf3b6b4..99e0e9f 100644 --- a/fc-cache/fc-cache.c +++ b/fc-cache/fc-cache.c @@ -187,8 +187,13 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, if (!cache) { - (*changed)++; - cache = FcDirCacheRead (dir, FcTrue, config); + if (!recursive) + cache = FcDirCacheRescan (dir, config); + else + { + (*changed)++; + cache = FcDirCacheRead (dir, FcTrue, config); + } if (!cache) { fprintf (stderr, "%s: error scanning\n", dir); @@ -386,6 +391,7 @@ main (int argc, char **argv) ret += scanDirs (list, config, FcTrue, really_force, verbose, FcFalse, &changed, NULL); FcStrListDone (list); } + FcStrSetDestroy (updateDirs); /* * Try to create CACHEDIR.TAG anyway. diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index dfc48f9..1a283a1 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -541,6 +541,9 @@ FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir); FcPublic FcCache * FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file); + +FcPublic FcCache * +FcDirCacheRescan (const FcChar8 *dir, FcConfig *config); FcPublic FcCache * FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config); diff --git a/src/fccache.c b/src/fccache.c index 10eacff..5173e0b 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -828,6 +828,19 @@ bail1: return NULL; } +FcCache * +FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs) +{ + FcCache *new; + FcFontSet *set = FcFontSetDeserialize (FcCacheSet (cache)); + const FcChar8 *dir = FcCacheDir (cache); + + new = FcDirCacheBuild (set, dir, dir_stat, dirs); + FcFontSetDestroy (set); + + return new; +} + /* write serialized state to the cache file */ FcBool FcDirCacheWrite (FcCache *cache, FcConfig *config) diff --git a/src/fcdir.c b/src/fcdir.c index b040a28..3bcd0b8 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -130,7 +130,12 @@ FcFileScanConfig (FcFontSet *set, if (FcFileIsDir (file)) return FcStrSetAdd (dirs, file); else - return FcFileScanFontConfig (set, blanks, file, config); + { + if (set) + return FcFileScanFontConfig (set, blanks, file, config); + else + return FcTrue; + } } FcBool @@ -306,6 +311,45 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) return cache; } +FcCache * +FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) +{ + FcCache *cache = FcDirCacheLoad (dir, config, NULL); + FcCache *new = NULL; + struct stat dir_stat; + FcStrSet *dirs; + + if (!cache) + return NULL; + if (FcStatChecksum (dir, &dir_stat) < 0) + goto bail; + dirs = FcStrSetCreate (); + if (!dirs) + goto bail; + + /* + * Scan the dir + */ + if (!FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config)) + goto bail1; + /* + * Rebuild the cache object + */ + new = FcDirCacheRebuild (cache, &dir_stat, dirs); + if (!new) + goto bail1; + FcDirCacheUnload (cache); + /* + * Write out the cache file, ignoring any troubles + */ + FcDirCacheWrite (new, config); + +bail1: + FcStrSetDestroy (dirs); +bail: + return new; +} + /* * Read (or construct) the cache for a directory */ diff --git a/src/fcfs.c b/src/fcfs.c index 941abba..21c6c7c 100644 --- a/src/fcfs.c +++ b/src/fcfs.c @@ -122,6 +122,28 @@ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s) return s_serialize; } + +FcFontSet * +FcFontSetDeserialize (const FcFontSet *set) +{ + int i; + FcFontSet *new = FcFontSetCreate (); + + if (!new) + return NULL; + for (i = 0; i < set->nfont; i++) + { + if (!FcFontSetAdd (new, FcPatternDuplicate (FcFontSetFont (set, i)))) + goto bail; + } + + return new; +bail: + FcFontSetDestroy (new); + + return NULL; +} + #define __fcfs__ #include "fcaliastail.h" #undef __fcfs__ diff --git a/src/fcint.h b/src/fcint.h index 362ea6f..cdf2dab 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -567,6 +567,9 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config); FcPrivate FcCache * FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs); +FcPrivate FcCache * +FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs); + FcPrivate FcBool FcDirCacheWrite (FcCache *cache, FcConfig *config); @@ -838,6 +841,9 @@ FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s); FcPrivate FcFontSet * FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s); +FcPrivate FcFontSet * +FcFontSetDeserialize (const FcFontSet *set); + /* fchash.c */ FcPrivate FcChar8 * FcHashGetSHA256Digest (const FcChar8 *input_strings, diff --git a/src/fcpat.c b/src/fcpat.c index 0614ac2..986cca3 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -33,6 +33,7 @@ FcPatternCreate (void) p = (FcPattern *) malloc (sizeof (FcPattern)); if (!p) return 0; + memset (p, 0, sizeof (FcPattern)); p->num = 0; p->size = 0; p->elts_offset = FcPtrToOffset (p, NULL); @@ -1310,6 +1311,7 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) } return head_serialized; } + #define __fcpat__ #include "fcaliastail.h" #include "fcftaliastail.h" -- 2.7.4