Improve the performance issue on rescanning directories
authorAkira TAGOH <akira@tagoh.org>
Thu, 5 Dec 2013 10:15:47 +0000 (19:15 +0900)
committerAkira TAGOH <akira@tagoh.org>
Fri, 20 Dec 2013 02:57:16 +0000 (11:57 +0900)
fc-cache/fc-cache.c
fontconfig/fontconfig.h
src/fccache.c
src/fcdir.c
src/fcfs.c
src/fcint.h
src/fcpat.c

index bf3b6b4..99e0e9f 100644 (file)
@@ -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.
index dfc48f9..1a283a1 100644 (file)
@@ -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);
index 10eacff..5173e0b 100644 (file)
@@ -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)
index b040a28..3bcd0b8 100644 (file)
@@ -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
  */
index 941abba..21c6c7c 100644 (file)
@@ -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__
index 362ea6f..cdf2dab 100644 (file)
@@ -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,
index 0614ac2..986cca3 100644 (file)
@@ -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"