15fca87535d94ba45c37c8088ffb571dcb024b9e
angie
  Mon Jul 8 10:31:31 2019 -0700
Increasing hashMaxSize to 30 to support dbSNP's 650M+ rs IDs.  Replaced assert with more informative error message when too-large size is passed in.  refs #23283

diff --git src/lib/hash.c src/lib/hash.c
index 2308617..989beb3 100644
--- src/lib/hash.c
+++ src/lib/hash.c
@@ -342,61 +342,69 @@
 	{
 	int num = ptToInt(hel->val);
 	sum += (long long)num;
 	}
     }
 return sum;
 }
 
 void hashIntReset(struct hash *hash)
 /* Reset all values in hash of ints to 0.  Reset element count to 0. */
 {
 memset(hash->table, 0, hash->size * sizeof hash->table[0]);
 hash->elCount = 0;
 }
 
+static int adjustPowerOfTwoSize(int powerOfTwoSize)
+/* If powerOfTwoSize is 0, return a reasonable default to use instead.  If powerOfTwoSize
+ * is out of range, errAbort.  Otherwise return powerOfTwoSize. */
+{
+if (powerOfTwoSize == 0)
+    powerOfTwoSize = 12;
+if (powerOfTwoSize > hashMaxSize || powerOfTwoSize < 0)
+    errAbort("hash powerOfTwoSize must be >= 0 and <= %d, but %d was passed in.",
+             hashMaxSize, powerOfTwoSize);
+return powerOfTwoSize;
+}
+
 struct hash *newHashLm(int powerOfTwoSize, struct lm *lm)
 /* Returns new hash table using the given lm.  Recommended lm block size is 256B to 64kB,
  * depending on powerOfTwoSize. */
 {
 struct hash *hash = lm ? lmAlloc(lm, sizeof(*hash)) : needMem(sizeof(*hash));
-if (powerOfTwoSize == 0)
-    powerOfTwoSize = 12;
-assert(powerOfTwoSize <= hashMaxSize && powerOfTwoSize > 0);
+powerOfTwoSize = adjustPowerOfTwoSize(powerOfTwoSize);
 hash->powerOfTwoSize = powerOfTwoSize;
 hash->size = (1<<powerOfTwoSize);
 hash->lm = lm;
 hash->mask = hash->size-1;
 if (lm)
     lmAllocArray(hash->lm, hash->table, hash->size);
 else
     AllocArray(hash->table, hash->size);
 hash->autoExpand = TRUE;
 hash->expansionFactor = defaultExpansionFactor;   /* Expand when elCount > size*expansionFactor */
 return hash;
 }
 
 struct hash *newHashExt(int powerOfTwoSize, boolean useLocalMem)
 /* Returns new hash table. Uses local memory optionally. */
 {
 struct hash *hash = NULL;
 if (useLocalMem)
     {
     int memBlockPower = 16;
-    if (powerOfTwoSize == 0)
-        powerOfTwoSize = 12;
-    assert(powerOfTwoSize <= hashMaxSize && powerOfTwoSize > 0);
+    powerOfTwoSize = adjustPowerOfTwoSize(powerOfTwoSize);
     /* Make size of memory block for allocator vary between
      * 256 bytes and 64k depending on size of table. */
     if (powerOfTwoSize < 8)
         memBlockPower = 8;
     else if (powerOfTwoSize < 16)
         memBlockPower = powerOfTwoSize;
     struct lm *ownLm = lmInit(1<<memBlockPower);
     hash = newHashLm(powerOfTwoSize, ownLm);
     hash->ownLm = TRUE;
     }
 else
     hash = newHashLm(powerOfTwoSize, NULL);
 return hash;
 }
 
@@ -407,34 +415,33 @@
 int i;
 for (i=0; i<hash->size; ++i)
     {
     struct hashEl *hel = hash->table[i];
     if (hel != NULL && hel->next != NULL)	    
 	slReverse(&hash->table[i]);
     }
 }
 
 void hashResize(struct hash *hash, int powerOfTwoSize)
 /* Resize the hash to a new size */
 {
 int oldHashSize = hash->size;
 struct hashEl **oldTable = hash->table;
 
-if (powerOfTwoSize == 0)
-    powerOfTwoSize = 12;
 if (powerOfTwoSize > hashMaxSize)
     powerOfTwoSize =  hashMaxSize;
+powerOfTwoSize = adjustPowerOfTwoSize(powerOfTwoSize);
 if (hash->powerOfTwoSize == powerOfTwoSize)
     return;
 
 assert(powerOfTwoSize <= hashMaxSize && powerOfTwoSize > 0);
 hash->powerOfTwoSize = powerOfTwoSize;
 hash->size = (1<<powerOfTwoSize);
 hash->mask = hash->size-1;
 
 if (hash->lm)
     lmAllocArray(hash->lm, hash->table, hash->size);
 else
     AllocArray(hash->table, hash->size);
 
 int i;
 struct hashEl *hel, *next;