Index: /trunk/src/kmk/file.c
===================================================================
--- /trunk/src/kmk/file.c	(revision 1902)
+++ /trunk/src/kmk/file.c	(revision 1903)
@@ -140,5 +140,5 @@
   if (!cached)
     {
-      file_key.hname = strcache2_lookup (&file_strcache, name, strlen (name));
+      file_key.hname = strcache2_lookup_file (&file_strcache, name, strlen (name));
       if (file_key.hname)
         f = hash_find_item_strcached (&files, &file_key);
Index: /trunk/src/kmk/incdep.c
===================================================================
--- /trunk/src/kmk/incdep.c	(revision 1902)
+++ /trunk/src/kmk/incdep.c	(revision 1903)
@@ -769,9 +769,9 @@
 {
   if (!entry->user)
-    entry->user = (void *)strcache2_add_hashed (&file_strcache,
-                                                (const char *)(entry + 1),
-                                                entry->length,
-                                                entry->hash1,
-                                                entry->hash2);
+    entry->user = (void *)strcache2_add_hashed_file (&file_strcache,
+                                                     (const char *)(entry + 1),
+                                                     entry->length,
+                                                     entry->hash1,
+                                                     entry->hash2);
   return (const char *)entry->user;
 }
Index: /trunk/src/kmk/strcache2.c
===================================================================
--- /trunk/src/kmk/strcache2.c	(revision 1902)
+++ /trunk/src/kmk/strcache2.c	(revision 1903)
@@ -268,8 +268,12 @@
 }
 
-#if 0 /* FIXME: Use this (salvaged from variable.c) */
+#ifdef _MSC_VER
+  typedef unsigned int int32_t;
+#else
+# include <stdint.h>
+#endif
 
 MY_INLINE int
-variable_hash_cmp_2_memcmp (const char *xs, const char *ys, unsigned int length)
+strcache2_memcmp_inline_short (const char *xs, const char *ys, unsigned int length)
 {
   /* short string compare - ~50% of the kBuild calls. */
@@ -345,5 +349,5 @@
 
 MY_INLINE int
-variable_hash_cmp_2_inlined (const char *xs, const char *ys, unsigned int length)
+strcache2_memcmp_inlined (const char *xs, const char *ys, unsigned int length)
 {
 #ifndef ELECTRIC_HEAP
@@ -450,10 +454,10 @@
 }
 
-#endif
-
 MY_INLINE int
 strcache2_is_equal (struct strcache2 *cache, struct strcache2_entry const *entry,
                     const char *str, unsigned int length, unsigned int hash1)
 {
+  assert (!cache->case_insensitive);
+
   /* the simple stuff first. */
   if (   entry == NULL
@@ -462,12 +466,30 @@
       return 0;
 
-  return !cache->case_insensitive
-    ? memcmp (entry + 1, str, length) == 0
+#if 1
+  return memcmp (entry + 1, str, length) == 0;
+#elif 0
+  return strcache2_memcmp_inlined (entry + 1, str, length) == 0;
+#else
+  return strcache2_memcmp_inline_short (entry + 1, str, length) == 0;
+#endif
+}
+
+MY_INLINE int
+strcache2_is_iequal (struct strcache2 *cache, struct strcache2_entry const *entry,
+                     const char *str, unsigned int length, unsigned int hash1)
+{
+  assert (cache->case_insensitive);
+
+  /* the simple stuff first. */
+  if (   entry == NULL
+      || entry->hash1 != hash1
+      || entry->length != length)
+      return 0;
+
 #if defined(_MSC_VER) || defined(__OS2__)
-    : _memicmp (entry + 1, str, length) == 0
+  return _memicmp (entry + 1, str, length) == 0;
 #else
-    : strncasecmp ((const char *)(entry + 1), str, length) == 0
+  return strncasecmp ((const char *)(entry + 1), str, length) == 0;
 #endif
-    ;
 }
 
@@ -632,13 +654,10 @@
   unsigned correct_hash;
 
-  correct_hash = cache->case_insensitive
-               ? strcache2_case_insensitive_hash_1 (str, length)
-               : strcache2_case_sensitive_hash_1 (str, length);
+  assert (!cache->case_insensitive);
+  correct_hash = strcache2_case_sensitive_hash_1 (str, length);
   MY_ASSERT_MSG (hash1 == correct_hash, ("%#x != %#x\n", hash1, correct_hash));
   if (hash2)
     {
-      correct_hash = cache->case_insensitive
-                   ? strcache2_case_insensitive_hash_2 (str, length)
-                   : strcache2_case_sensitive_hash_2 (str, length);
+      correct_hash = strcache2_case_sensitive_hash_2 (str, length);
       MY_ASSERT_MSG (hash2 == correct_hash, ("%#x != %#x\n", hash2, correct_hash));
     }
@@ -687,5 +706,5 @@
 }
 
-/* The public lookup string interface. */
+/* The public lookup (case sensitive) string interface. */
 const char *
 strcache2_lookup (struct strcache2 *cache, const char *str, unsigned int length)
@@ -757,5 +776,5 @@
   idx = hash1 & cache->hash_mask;
   entry = cache->hash_tab[idx];
-  if (strcache2_is_equal (cache, entry, str, length, hash1))
+  if (strcache2_is_iequal (cache, entry, str, length, hash1))
     return (const char *)(entry + 1);
   if (!entry)
@@ -769,5 +788,5 @@
       idx &= cache->hash_mask;
       entry = cache->hash_tab[idx];
-      if (strcache2_is_equal (cache, entry, str, length, hash1))
+      if (strcache2_is_iequal (cache, entry, str, length, hash1))
         return (const char *)(entry + 1);
 
@@ -781,5 +800,5 @@
               entry = cache->hash_tab[idx];
               cache->collision_3rd_count++;
-              if (strcache2_is_equal (cache, entry, str, length, hash1))
+              if (strcache2_is_iequal (cache, entry, str, length, hash1))
                 return (const char *)(entry + 1);
             }
@@ -792,5 +811,116 @@
 }
 
-/* strcache_ilookup later */
+/* The public add string interface for prehashed case insensitive strings.
+   Use strcache2_hash_istr to calculate the hash of a string. */
+const char *
+strcache2_iadd_hashed (struct strcache2 *cache, const char *str, unsigned int length,
+                       unsigned int hash1, unsigned int hash2)
+{
+  struct strcache2_entry const *entry;
+  unsigned int idx;
+#ifndef NDEBUG
+  unsigned correct_hash;
+
+  assert (cache->case_insensitive);
+  correct_hash = strcache2_case_insensitive_hash_1 (str, length);
+  MY_ASSERT_MSG (hash1 == correct_hash, ("%#x != %#x\n", hash1, correct_hash));
+  if (hash2)
+    {
+      correct_hash = strcache2_case_insensitive_hash_2 (str, length);
+      MY_ASSERT_MSG (hash2 == correct_hash, ("%#x != %#x\n", hash2, correct_hash));
+    }
+#endif /* NDEBUG */
+
+  cache->lookup_count++;
+
+  /* Lookup the entry in the hash table, hoping for an
+     early match. */
+  idx = hash1 & cache->hash_mask;
+  entry = cache->hash_tab[idx];
+  if (strcache2_is_iequal (cache, entry, str, length, hash1))
+    return (const char *)(entry + 1);
+  if (entry)
+    {
+      cache->collision_1st_count++;
+
+      if (!hash2)
+        hash2 = strcache2_case_insensitive_hash_2 (str, length);
+      idx += hash2;
+      idx &= cache->hash_mask;
+      entry = cache->hash_tab[idx];
+      if (strcache2_is_iequal (cache, entry, str, length, hash1))
+        return (const char *)(entry + 1);
+
+      if (entry)
+        {
+          cache->collision_2nd_count++;
+          do
+            {
+              idx += hash2;
+              idx &= cache->hash_mask;
+              entry = cache->hash_tab[idx];
+              cache->collision_3rd_count++;
+              if (strcache2_is_iequal (cache, entry, str, length, hash1))
+                return (const char *)(entry + 1);
+            }
+          while (entry);
+        }
+    }
+
+  /* Not found, add it at IDX. */
+  return strcache2_enter_string (cache, idx, str, length, hash1, hash2);
+}
+
+/* The public lookup (case insensitive) string interface. */
+const char *
+strcache2_lookup (struct strcache2 *cache, const char *str, unsigned int length)
+{
+  struct strcache2_entry const *entry;
+  unsigned int hash2;
+  unsigned int hash1 = strcache2_case_insensitive_hash_1 (str, length);
+  unsigned int idx;
+
+  assert (cache->case_insensitive);
+
+  cache->lookup_count++;
+
+  /* Lookup the entry in the hash table, hoping for an
+     early match. */
+  idx = hash1 & cache->hash_mask;
+  entry = cache->hash_tab[idx];
+  if (strcache2_is_iequal (cache, entry, str, length, hash1))
+    return (const char *)(entry + 1);
+  if (!entry)
+    hash2 = 0;
+  else
+    {
+      cache->collision_1st_count++;
+
+      hash2 = strcache2_case_insensitive_hash_2 (str, length);
+      idx += hash2;
+      idx &= cache->hash_mask;
+      entry = cache->hash_tab[idx];
+      if (strcache2_is_iequal (cache, entry, str, length, hash1))
+        return (const char *)(entry + 1);
+
+      if (entry)
+        {
+          cache->collision_2nd_count++;
+          do
+            {
+              idx += hash2;
+              idx &= cache->hash_mask;
+              entry = cache->hash_tab[idx];
+              cache->collision_3rd_count++;
+              if (strcache2_is_iequal (cache, entry, str, length, hash1))
+                return (const char *)(entry + 1);
+            }
+          while (entry);
+        }
+    }
+
+  /* Not found. */
+  return NULL;
+}
 
 #endif /* HAVE_CASE_INSENSITIVE_FS */
Index: /trunk/src/kmk/strcache2.h
===================================================================
--- /trunk/src/kmk/strcache2.h	(revision 1902)
+++ /trunk/src/kmk/strcache2.h	(revision 1903)
@@ -95,12 +95,19 @@
 const char *strcache2_add (struct strcache2 *cache, const char *str, unsigned int length);
 const char *strcache2_iadd (struct strcache2 *cache, const char *str, unsigned int length);
-#ifdef HAVE_CASE_INSENSITIVE_FS
-# define strcache2_add_file(cache, str, length) strcache2_iadd((cache), (str), (length))
-#else
-# define strcache2_add_file(cache, str, length) strcache2_add((cache), (str), (length))
-#endif
 const char *strcache2_add_hashed (struct strcache2 *cache, const char *str, unsigned int length,
                                   unsigned int hash1, unsigned int hash2);
+const char *strcache2_iadd_hashed (struct strcache2 *cache, const char *str, unsigned int length,
+                                   unsigned int hash1, unsigned int hash2);
 const char *strcache2_lookup (struct strcache2 *cache, const char *str, unsigned int length);
+const char *strcache2_ilookup (struct strcache2 *cache, const char *str, unsigned int length);
+#ifdef HAVE_CASE_INSENSITIVE_FS
+# define strcache2_add_file         strcache2_iadd
+# define strcache2_add_hashed_file  strcache2_iadd_hashed
+# define strcache2_lookup_file      strcache2_ilookup
+#else
+# define strcache2_add_file         strcache2_add
+# define strcache2_add_hashed_file  strcache2_add_hashed
+# define strcache2_lookup_file      strcache2_lookup
+#endif
 int strcache2_is_cached (struct strcache2 *cache, const char *str);
 int strcache2_verify_entry (struct strcache2 *cache, const char *str);
