ppc4xx/POST: Change ethernet test loop count to a default of 10
[oweals/u-boot.git] / lib / hashtable.c
index 2f3b5c8d1026eaa7cc9edd0864e505fcd9056d40..7ac3dddda693897f2a08cfda4ea682e943ab3e39 100644 (file)
 # include <linux/string.h>
 #endif
 
+#ifndef        CONFIG_ENV_MIN_ENTRIES  /* minimum number of entries */
+#define        CONFIG_ENV_MIN_ENTRIES 64
+#endif
+#ifndef        CONFIG_ENV_MAX_ENTRIES  /* maximum number of entries */
+#define        CONFIG_ENV_MAX_ENTRIES 512
+#endif
+
 #include "search.h"
 
 /*
  * [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
- * [Knuth]            The Art of Computer Programming, part 3 (6.4)
+ * [Knuth]           The Art of Computer Programming, part 3 (6.4)
  */
 
 /*
@@ -245,7 +252,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
 
        if (htab->table[idx].used) {
                /*
-                 * Further action might be required according to the
+                * Further action might be required according to the
                 * action value.
                 */
                unsigned hval2;
@@ -276,8 +283,8 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
 
                do {
                        /*
-                         * Because SIZE is prime this guarantees to
-                         * step through all available indices.
+                        * Because SIZE is prime this guarantees to
+                        * step through all available indices.
                         */
                        if (idx <= hval2)
                                idx = htab->size + idx - hval2;
@@ -316,8 +323,8 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
        /* An empty bucket has been found. */
        if (action == ENTER) {
                /*
-                 * If table is full and another entry should be
-                 * entered return with error.
+                * If table is full and another entry should be
+                * entered return with error.
                 */
                if (htab->filled == htab->size) {
                        __set_errno(ENOMEM);
@@ -636,15 +643,24 @@ int himport_r(struct hsearch_data *htab,
         * table size is based on heuristics: in a sample of some 70+
         * existing systems we found an average size of 39+ bytes per entry
         * in the environment (for the whole key=value pair). Assuming a
-        * size of 7 per entry (= safety factor of >5) should provide enough
-        * safety margin for any existing environment definitons and still
+        * size of 8 per entry (= safety factor of ~5) should provide enough
+        * safety margin for any existing environment definitions and still
         * allow for more than enough dynamic additions. Note that the
         * "size" argument is supposed to give the maximum enviroment size
-        * (CONFIG_ENV_SIZE).
+        * (CONFIG_ENV_SIZE).  This heuristics will result in
+        * unreasonably large numbers (and thus memory footprint) for
+        * big flash environments (>8,000 entries for 64 KB
+        * envrionment size), so we clip it to a reasonable value.
+        * On the other hand we need to add some more entries for free
+        * space when importing very small buffers. Both boundaries can
+        * be overwritten in the board config file if needed.
         */
 
        if (!htab->table) {
-               int nent = size / 7;
+               int nent = CONFIG_ENV_MIN_ENTRIES + size / 8;
+
+               if (nent > CONFIG_ENV_MAX_ENTRIES)
+                       nent = CONFIG_ENV_MAX_ENTRIES;
 
                debug("Create Hash Table: N=%d\n", nent);
 
@@ -705,17 +721,19 @@ int himport_r(struct hsearch_data *htab,
 
                hsearch_r(e, ENTER, &rv, htab);
                if (rv == NULL) {
-                       printf("himport_r: can't insert \"%s=%s\" into hash table\n", name, value);
+                       printf("himport_r: can't insert \"%s=%s\" into hash table\n",
+                               name, value);
                        return 0;
                }
 
-               debug("INSERT: %p ==> name=\"%s\" value=\"%s\"\n", rv, name,
-                      value);
-               debug("        table = %p, size = %d, filled = %d\n", htab,
-                      htab->size, htab->filled);
+               debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n",
+                       htab, htab->filled, htab->size,
+                       rv, name, value);
        } while ((dp < data + size) && *dp);    /* size check needed for text */
                                                /* without '\0' termination */
+       debug("INSERT: free(data = %p)\n", data);
        free(data);
 
+       debug("INSERT: done\n");
        return 1;               /* everything OK */
 }