]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
search cache
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 23 Dec 2011 20:14:34 +0000 (21:14 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 23 Dec 2011 20:14:34 +0000 (21:14 +0100)
grub-core/commands/search.c

index efb44c25e276ee8d7c722e06d4cdbaa4ba1962d8..d5117baefdebb910abb1ff3c787e3eee94e3f1ce 100644 (file)
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
+struct cache_entry
+{
+  struct cache_entry *next;
+  char *key;
+  char *value;
+};
+
+static struct cache_entry *cache;
+
 void
 FUNC_NAME (const char *key, const char *var, int no_floppy,
           char **hints, unsigned nhints)
 {
   int count = 0;
+  int is_cache = 0;
   grub_fs_autoload_hook_t saved_autoload;
 
   auto int iterate_device (const char *name);
@@ -50,6 +60,12 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
        name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
       return 0;
 
+#ifdef DO_SEARCH_FS_UUID
+#define compare_fn grub_strcasecmp
+#else
+#define compare_fn grub_strcmp
+#endif
+
 #ifdef DO_SEARCH_FILE
       {
        char *buf;
@@ -81,10 +97,8 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
            fs = grub_fs_probe (dev);
 
 #ifdef DO_SEARCH_FS_UUID
-#define compare_fn grub_strcasecmp
 #define read_fn uuid
 #else
-#define compare_fn grub_strcmp
 #define read_fn label
 #endif
 
@@ -106,6 +120,31 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
       }
 #endif
 
+    if (!is_cache && found && count == 0)
+      {
+       struct cache_entry *cache_ent;
+       cache_ent = grub_malloc (sizeof (*cache_ent));
+       if (cache_ent)
+         {
+           cache_ent->key = grub_strdup (key);
+           cache_ent->value = grub_strdup (name);
+           if (cache_ent->value && cache_ent->key)
+             {
+               cache_ent->next = cache;
+               cache = cache_ent;
+             }
+           else
+             {
+               grub_free (cache_ent->value);
+               grub_free (cache_ent->key);
+               grub_free (cache_ent);
+               grub_errno = GRUB_ERR_NONE;
+             }
+         }
+       else
+         grub_errno = GRUB_ERR_NONE;
+      }
+
     if (found)
       {
        count++;
@@ -143,6 +182,32 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
   void try (void)    
   {
     unsigned i;
+    struct cache_entry **prev;
+    struct cache_entry *cache_ent;
+
+    for (prev = &cache, cache_ent = *prev; cache_ent;
+        prev = &cache_ent->next, cache_ent = *prev)
+      if (compare_fn (cache_ent->key, key) == 0)
+       break;
+    if (cache_ent)
+      {
+       is_cache = 1;
+       if (iterate_device (cache_ent->value))
+         {
+           is_cache = 0;
+           return;
+         }
+       is_cache = 0;
+       /* Cache entry was outdated. Remove it.  */
+       if (!count)
+         {
+           grub_free (cache_ent->key);
+           grub_free (cache_ent->value);
+           grub_free (cache_ent);
+           *prev = cache_ent->next;
+         }
+      }
+
     for (i = 0; i < nhints; i++)
       {
        char *end;