7466d1654758a960990796f5c049e09e475f7766
tdreszer
  Thu Dec 1 17:12:06 2011 -0800
More timing in hgFileUi and hgFileSearch led to important efficiency changes.  Most notable, I am relying upon cached rsync results now to improve speed.
diff --git src/hg/lib/mdb.c src/hg/lib/mdb.c
index 4cf73be..2cbfb27 100644
--- src/hg/lib/mdb.c
+++ src/hg/lib/mdb.c
@@ -2151,74 +2151,103 @@
 onePair = onePair->next;
 for(; onePair != NULL; onePair = onePair->next)
     dyStringPrintf(dyTerms,",%s",onePair->name);
 mdbObjsSortOnVars(mdbObjs,dyStringContents(dyTerms));
 dyStringFree(&dyTerms);
 }
 
 void mdbObjsSortOnCv(struct mdbObj **mdbObjs, boolean includeHidden)
 // Puts obj->vars in order based upon cv.ra typeOfTerms priority,
 //  then case-sensitively sorts all objs in list based upon that var order.
 {  // NOTE: assumes all var pairs match (e.g. every obj has cell,treatment,antibody,... and missing treatment messes up sort)
 mdbObjReorderByCv(*mdbObjs, includeHidden);
 slSort(mdbObjs, mdbObjVarCmp);  // While sort will not be perfect (given missing values) it does a good job none the less.
 }
 
+boolean mdbObjRemoveOneVar(struct mdbObj *mdbObj, char *var, char *val)
+// returns TRUE if var (and optional val) are found and surgically removed from one mdbObj
+{
+struct mdbVar *lastVar = NULL;
+struct mdbVar *mdbVar = mdbObj->vars;
+for(;mdbVar != NULL;lastVar=mdbVar,mdbVar=mdbVar->next)
+    {
+    if (sameWord(mdbVar->var,var))
+        {
+        if (val && differentString(mdbVar->val,val))
+            break; // No need to continue
+        if (lastVar != NULL)
+            lastVar->next = mdbVar->next;
+        else
+            mdbObj->vars = mdbVar->next;
+        mdbVar->next = NULL;
+        if (mdbObj->varHash != NULL)
+            hashRemove(mdbObj->varHash,mdbVar->var);
+        mdbVarFree(&mdbVar);
+        return TRUE;
+        }
+    }
+return FALSE;
+}
+
 void mdbObjRemoveVars(struct mdbObj *mdbObjs, char *vars)
 // Prunes list of vars for an object, freeing the memory.  Doesn't touch DB.
 {
-char *cloneLine = NULL;
 int count = 0;
 char **words = NULL;
 if(vars != NULL)
     {
-    cloneLine = cloneString(vars);
-    count = chopByWhite(cloneLine,NULL,0);
+    count = chopByWhite(vars,NULL,0);
+    if (count > 1)
+        {
     words = needMem(sizeof(char *) * count);
-    count = chopByWhite(cloneLine,words,count);
+        count = chopByWhite(cloneString(vars),words,count);
+        }
     }
 struct mdbObj *mdbObj = NULL;
 for( mdbObj=mdbObjs; mdbObj!=NULL; mdbObj=mdbObj->next )
     {
-    int ix;
-    struct mdbVar *keepTheseVars = NULL;
-
-    if(count == 0 && mdbObj->varHash != NULL)
+    if (count == 0)
+        {
+        if(mdbObj->varHash != NULL)
         hashFree(&mdbObj->varHash);
-
+        mdbVarsFree(&mdbObj->vars);
+        }
+    else if (count == 1)
+        mdbObjRemoveOneVar(mdbObj,vars,NULL);
+    else
+        {
+        struct mdbVar *keepTheseVars = NULL;
     struct mdbVar *mdbVar = NULL;
     while((mdbVar = slPopHead(&(mdbObj->vars))) != NULL)
         {
-        if(count == 0)
-            ix = 1;
-        else
-            ix = stringArrayIx(mdbVar->var,words,count);
+            int ix = stringArrayIx(mdbVar->var,words,count);
         if(ix < 0)
             slAddHead(&keepTheseVars,mdbVar);
         else
             {
             if(count != 0 && mdbObj->varHash != NULL)
                 hashRemove(mdbObj->varHash, mdbVar->var);
 
             mdbVarFree(&mdbVar);
             }
         }
 
     if(keepTheseVars != NULL)
         slReverse(&keepTheseVars);
     mdbObj->vars = keepTheseVars;
     }
+    }
     if(words != NULL)
         freeMem(words);
 }
 
 void mdbObjRemoveHiddenVars(struct mdbObj *mdbObjs)
 // Prunes list of vars for mdb objs that have been declared as hidden in cv.ra typeOfTerms
 {
 // make comma delimited list of hidden vars
 struct hash *cvTermTypes = (struct hash *)cvTermTypeHash();
 struct hashEl *el, *elList = hashElListHash(cvTermTypes);
 struct dyString *dyRemoveVars = dyStringNew(256);
 
 for (el = elList; el != NULL; el = el->next)
     {
     if (cvTermIsHidden(el->name))