814da1fd6d9e117ec28ae41a2d560dbd957669de
tdreszer
  Tue Nov 29 12:47:39 2011 -0800
Improved cv efficiency by only reading the cv.ra file once.
diff --git src/hg/lib/cv.c src/hg/lib/cv.c
index e27c88d..64b3e73 100644
--- src/hg/lib/cv.c
+++ src/hg/lib/cv.c
@@ -96,75 +96,63 @@
     {
     char *root = hCgiRoot();
     if (root == NULL || *root == 0)
         root = "/usr/local/apache/cgi-bin/"; // Make this check out sandboxes?
     safef(filePath, sizeof(filePath), "%s/encode/%s", root,CV_FILE_NAME);
     }
 if(!fileExists(filePath))
     errAbort("Error: can't locate %s; %s doesn't exist\n", CV_FILE_NAME, filePath);
 return filePath;
 }
 
 const struct hash *cvTermHash(const char *term)
 // returns a hash of hashes of a term which should be defined in cv.ra
 // NOTE: in static memory: DO NOT FREE
 {
-static struct hash *cvHashOfHashOfHashes = NULL;
+static struct hash *cvHashOfHashesOfHashes = NULL;
+if (cvHashOfHashesOfHashes == NULL) // gets them all at once.
+    cvHashOfHashesOfHashes = raReadThreeLevels((char *)cvFile(), CV_TERM,CV_TYPE);
+
 if (sameString(term,CV_TERM_CELL))
     term = CV_UGLY_TERM_CELL_LINE;
 else if (sameString(term,CV_TERM_ANTIBODY))
     term = CV_UGLY_TERM_ANTIBODY;
 
-if (cvHashOfHashOfHashes == NULL)
-    cvHashOfHashOfHashes = hashNew(9);
-
-struct hashEl *hel = hashLookup(cvHashOfHashOfHashes, (char *) term);
-struct hash *cvHashForTerm = NULL;
-
-// Establish cv hash of Term Types if it doesn't already exist
-if (hel == NULL)
-    {
-    cvHashForTerm = raReadWithFilter((char *)cvFile(), CV_TERM,CV_TYPE,(char *)term);
-    hashAdd(cvHashOfHashOfHashes,(char *)term,cvHashForTerm);
-    }
-else
-    cvHashForTerm = hel->val;
-
-return cvHashForTerm;
+return hashFindVal(cvHashOfHashesOfHashes,(char *)term);
 }
 
 const struct hash *cvOneTermHash(const char *type,const char *term)
 // returns a hash for a single term of a given type
 // NOTE: in static memory: DO NOT FREE
 {
 const struct hash *typeHash = cvTermHash(type);
 if (typeHash != NULL)
     return hashFindVal((struct hash *)typeHash,(char *)term);
 return NULL;
 }
 
 const struct hash *cvTermTypeHash()
 // returns a hash of hashes of mdb and controlled vocabulary (cv) term types
 // Those terms should contain label,description,searchable,cvDefined,hidden
 // NOTE: in static memory: DO NOT FREE
 { // NOTE: "typeOfTerm" is specialized, so don't use cvTermHash
 static struct hash *cvHashOfTermTypes = NULL;
 
 // Establish cv hash of Term Types if it doesn't already exist
 if (cvHashOfTermTypes == NULL)
     {
-    cvHashOfTermTypes = raReadWithFilter((char *)cvFile(), CV_TERM,CV_TYPE,CV_TOT);
+    cvHashOfTermTypes = (struct hash *)cvTermHash(CV_TOT);
     // Patch up an ugly inconsistency with 'cell'
     struct hash *cellHash = hashRemove(cvHashOfTermTypes,CV_UGLY_TOT_CELLTYPE);
     if (cellHash)
         {
         hashAdd(cvHashOfTermTypes,CV_TERM_CELL,cellHash);
         hashReplace(cellHash, CV_TERM, cloneString(CV_TERM_CELL)); // spilling memory of 'cellType' val
         }
     struct hash *abHash = hashRemove(cvHashOfTermTypes,CV_UGLY_TERM_ANTIBODY);
     if (abHash)
         {
         hashAdd(cvHashOfTermTypes,CV_TERM_ANTIBODY,abHash);
         hashReplace(abHash, CV_TERM, cloneString(CV_TERM_ANTIBODY)); // spilling memory of 'Antibody' val
         }
     }
 
@@ -388,45 +376,42 @@
 // For example anitobody is cv defined but expId isn't
 {
 struct hash *termTypeHash = (struct hash *)cvTermTypeHash();
 struct hash *termHash = hashFindVal(termTypeHash,(char *)term);
 if (termHash != NULL)
     {
     char *setting = hashFindVal(termHash,CV_TOT_CV_DEFINED);
     return SETTING_IS_ON(setting);
     }
 return FALSE;
 }
 
 boolean cvTermIsEmpty(const char *term,const char *val)
 // returns TRUE if term has validation of "cv or None" and the val is None
 {
-if (val == NULL)
+if (isEmpty(val))
     return TRUE; // Empty whether it is supposed to be or not
 
-struct hash *termTypeHash = (struct hash *)cvTermTypeHash();
-struct hash *termHash = hashFindVal(termTypeHash,(char *)term);
-if (termHash != NULL)
-    {
-    char *validationRule = hashFindVal(termHash,CV_VALIDATE);
+if (differentString(val,MDB_VAL_ENCODE_EDV_NONE)) // Don't even bother if not None
+    return FALSE;
+char *validationRule = (char *)cvValidationRule(term);
     if (validationRule != NULL)
         {           // Currently only supporting special case for "None"
         if (sameString(validationRule,CV_VALIDATE_CV_OR_NONE)
         && sameString(val,MDB_VAL_ENCODE_EDV_NONE))
             return TRUE;
         }
-    }
 return FALSE;
 }
 
 boolean cvValidateTerm(const char *term,const char *val,char *reason,int len)
 // returns TRUE if term is valid.  Can pass in a reason buffer of len to get reason.
 {
 if (reason != NULL)
     *reason = '\0';
 
 char *validationRule = (char *)cvValidationRule(term);
 if (validationRule == NULL)
     {
     if (reason != NULL)
         safef(reason,len,"ERROR in %s: Term '%s' in typeOfTerms but has no '%s' setting.",CV_FILE_NAME,(char *)term,CV_VALIDATE);
     return FALSE;