Add really rudimentary rules caching support
authorDaniel Stone <daniel@fooishbar.org>
Tue, 22 Jun 2010 14:54:52 +0000 (15:54 +0100)
committerDaniel Stone <daniel@fooishbar.org>
Tue, 22 Jun 2010 14:57:16 +0000 (15:57 +0100)
Keep the parsed form of the last-used rules file around, and reuse that
if we get asked for the same ruleset.  If not, bin it and cache the
other one.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
src/xkbcomp/xkbcomp.c

index f8109d4..e801a7b 100644 (file)
@@ -76,30 +76,43 @@ XkbKeymapFileFromComponents(const XkbComponentNamesPtr ktcsg)
 static XkbComponentNamesPtr
 XkbComponentsFromRules(const char *rules, const XkbRF_VarDefsPtr defs)
 {
-    FILE *rulesFile;
-    char *rulesPath;
-    XkbRF_RulesPtr loaded;
+    FILE *rulesFile = NULL;
+    char *rulesPath = NULL;
+    static XkbRF_RulesPtr loaded = NULL;
+    static char *cached_name = NULL;
     XkbComponentNamesPtr names = NULL;
 
-    rulesFile = XkbFindFileInPath((char *)rules, XkmRulesFile, &rulesPath);
-    if (!rulesFile) {
-        ERROR("could not find \"%s\" rules in XKB path\n", rules);
-        goto out;
+    if (!cached_name || strcmp(rules, cached_name) != 0) {
+        if (loaded)
+            XkbcRF_Free(loaded, True);
+        loaded = NULL;
+        free(cached_name);
+        cached_name = NULL;
     }
 
-    if (!(loaded = _XkbTypedCalloc(1, XkbRF_RulesRec))) {
-        ERROR("failed to allocate XKB rules\n");
-        goto unwind_file;
-    }
+    if (!loaded) {
+        rulesFile = XkbFindFileInPath((char *)rules, XkmRulesFile, &rulesPath);
+        if (!rulesFile) {
+            ERROR("could not find \"%s\" rules in XKB path\n", rules);
+            goto out;
+        }
+
+        if (!(loaded = _XkbTypedCalloc(1, XkbRF_RulesRec))) {
+            ERROR("failed to allocate XKB rules\n");
+            goto unwind_file;
+        }
+
+        if (!XkbcRF_LoadRules(rulesFile, loaded)) {
+            ERROR("failed to load XKB rules \"%s\"\n", rulesPath);
+            goto unwind_file;
+        }
 
-    if (!XkbcRF_LoadRules(rulesFile, loaded)) {
-        ERROR("failed to load XKB rules \"%s\"\n", rulesPath);
-        goto unwind_rules;
+        cached_name = strdup(rules);
     }
 
     if (!(names = _XkbTypedCalloc(1, XkbComponentNamesRec))) {
         ERROR("failed to allocate XKB components\n");
-        goto unwind_rules;
+        goto unwind_file;
     }
 
     if (!XkbcRF_GetComponents(loaded, defs, names)) {
@@ -114,10 +127,9 @@ XkbComponentsFromRules(const char *rules, const XkbRF_VarDefsPtr defs)
         ERROR("no components returned from XKB rules \"%s\"\n", rulesPath);
     }
 
-unwind_rules:
-    XkbcRF_Free(loaded, True);
 unwind_file:
-    fclose(rulesFile);
+    if (rulesFile)
+        fclose(rulesFile);
     free(rulesPath);
 out:
     return names;