static int oneBam(const bam1_t *bam, void *data, bam_hdr_t *header) /* This is called on each record retrieved from a .bam file. */ { const bam1_core_t *core = &bam->core; if (core->flag & BAM_FUNMAP) return 0; struct bamTrackData *btd = (struct bamTrackData *)data; if (sameString(bam1_qname(bam), btd->itemName)) { if (btd->pairHash == NULL || (core->flag & BAM_FPAIRED) == 0) { if (core->pos == btd->itemStart) { printf("<B>Read name:</B> %s<BR>\n", btd->itemName); singleBamDetails(bam); } } else { bam1_t *firstBam = (bam1_t *)hashFindVal(btd->pairHash, btd->itemName); if (firstBam == NULL) hashAdd(btd->pairHash, btd->itemName, bamClone(bam)); else { bamPairDetails(firstBam, bam); hashRemove(btd->pairHash, btd->itemName); } } } return 0; }
struct hashEl *hashReplace(struct hash *hash, char *name, void *val) /* Replace an existing element in hash table, or add it if not present. */ { if (hashLookup(hash, name)) hashRemove(hash, name); return hashAdd(hash, name, val); }
static struct trackDb * pruneOrphans(struct trackDb *tdbList, struct hash *trackHash) /* Prune out orphans with no parents of the right release */ { boolean done = FALSE; struct trackDb *tdb; struct trackDb *nonOrphanList = NULL; while (!done) { done = TRUE; nonOrphanList = NULL; while ((tdb = slPopHead(&tdbList)) != NULL) { char *parentName = cloneFirstWord(trackDbLocalSetting(tdb, "parent")); struct hashEl *hel = NULL; if (parentName != NULL) { hel = hashLookup(trackHash, parentName); } if (parentName == NULL || hel != NULL) { slAddHead(&nonOrphanList, tdb); } else { verbose(3,"pruneOrphans: removing '%s'\n", tdb->track); hashRemove(trackHash, tdb->track); done = FALSE; } freeMem(parentName); } tdbList = nonOrphanList; } return tdbList; }
static struct trackDb * pruneRelease(struct trackDb *tdbList) /* Prune out alternate track entries for another release */ { /* Build up list that only includes things in this release. Release * can be inherited from parents. */ struct trackDb *tdb; struct trackDb *relList = NULL; struct hash *haveHash = hashNew(3); while ((tdb = slPopHead(&tdbList)) != NULL) { char *rel = trackDbSetting(tdb, "release"); unsigned trackRelBits = buildReleaseBits(rel); if (trackRelBits & releaseBit) { /* we want to include this track, check to see if we already have it */ struct hashEl *hel; if ((hel = hashLookup(haveHash, tdb->track)) != NULL) errAbort("found two copies of table %s: one with release %s, the other %s\n", tdb->track, (char *)hel->val, release); hashAdd(haveHash, tdb->track, rel); hashRemove(tdb->settingsHash, "release"); slAddHead(&relList, tdb); } else verbose(3,"pruneRelease: removing '%s', release: '%s' != '%s'\n", tdb->track, rel, release); } freeHash(&haveHash); return relList; }
void hashMustRemove(struct hash *hash, char *name) /* Remove item of the given name from hash table, or error * if not present */ { if (hashRemove(hash, name) == NULL) errAbort("attempt to remove non-existant %s from hash", name); }
struct psl *getPslList(struct hash *pHash, struct bed *bList) /* Get psls for alignments in bed file */ { struct bed *bedEl; struct psl *psl = NULL, *pslNext = NULL, *pslList = NULL; struct hashEl *hEl; char *key = NULL; for (bedEl = bList; bedEl != NULL; bedEl = bedEl->next) { /* create key for hash look up */ key = createKey(bedEl->name, bedEl->chrom, bedEl->chromStart, bedEl->chromEnd); hEl = hashLookup(pHash, key); if (hEl != NULL) { /* Get psl and then add to list */ psl = hEl->val; if (psl != NULL) { slSafeAddHead(&pslList, psl); /* Remove from hash */ hashRemove(pHash, key); } } } return pslList; }
void removePage(TupleIdBitmap* tupleIdBitmap, BlockNumber pageNumber) { Bool itemWasPresentBeforeRemoval = hashRemove(tupleIdBitmap->pageTable, (void*)&pageNumber) != NULL; if (itemWasPresentBeforeRemoval) { tupleIdBitmap->numberOfEntries--; tupleIdBitmap->numberOfPages--; } }
struct hashEl *addHashElUnique(struct hash *hash, char *name, void *val) /* Adds new element to hash table. If not unique, remove old element */ /* before adding new one. Avoids replicate entries in the table */ { if (hashLookup(hash, name) != NULL) /* if item in hash already, remove first */ hashRemove(hash, name); /* then add element to hash table */ return hashAdd(hash, name, val); }
int ObjCache::add(void *obj,void **victim) { *victim=0; HashNode *hnode = hashFind(obj); //printf("hnode=%p\n",hnode); if (hnode) // move object to the front of the LRU list, since it is used // most recently { //printf("moveToFront=%d\n",hnode->index); moveToFront(hnode->index); m_hits++; } else // object not in the cache. { void *lruObj=0; if (m_freeCacheNodes!=-1) // cache not full -> add element to the cache { // remove element from free list int index = m_freeCacheNodes; m_freeCacheNodes = m_cache[index].next; // add to head of the list if (m_tail==-1) { m_tail = index; } m_cache[index].prev = -1; m_cache[index].next = m_head; if (m_head!=-1) { m_cache[m_head].prev = index; } m_head = index; m_count++; } else // cache full -> replace element in the cache { //printf("Cache full!\n"); lruObj = m_cache[m_tail].obj; hashRemove(lruObj); moveToFront(m_tail); // m_tail indexes the emptied element, which becomes m_head } //printf("numEntries=%d size=%d\n",m_numEntries,m_size); m_cache[m_head].obj = obj; hnode = hashInsert(obj); hnode->index = m_head; *victim = lruObj; m_misses++; } return m_head; }
static struct hgFindSpec * pruneRelease(struct hgFindSpec *hfsList) /* Prune out alternate track entries for another release */ { /* Build up list that only includes things in this release. Release * can be inherited from parents. */ struct hgFindSpec *hfs; struct hgFindSpec *relList = NULL; struct hash *haveHash = hashNew(3); while ((hfs = slPopHead(&hfsList)) != NULL) { char *rel = hgFindSpecSetting(hfs, "release"); unsigned hfsRelBits = buildReleaseBits(rel); if (hfsRelBits & releaseBit) { /* we want to include this track, check to see if we already have it */ struct hashEl *hel; if ((hel = hashLookup(haveHash, hfs->searchName)) != NULL) { // TODO restore this warning to errAbort // This has been temporarily changed to a warning to avoid everybody being held up. char *one = (char *)hel->val; char *other = release; if (!one) one = "none"; if (!other) other = "none"; warn("ERROR: found two or more copies of %s: one with release %s, the other %s\n", hfs->searchName, one, other); } else { hashAdd(haveHash, hfs->searchName, rel); hashRemove(hfs->settingsHash, "release"); slAddHead(&relList, hfs); } } else verbose(3,"pruneRelease: removing '%s', release: '%s' != '%s'\n", hfs->searchName, rel, release); } freeHash(&haveHash); return relList; }
void ObjCache::del(int index) { assert(index!=-1); assert(m_cache[index].obj!=0); hashRemove(m_cache[index].obj); moveToFront(index); m_head = m_cache[index].next; if (m_head==-1) m_tail=-1; else m_cache[m_head].prev=-1; m_cache[index].obj=0; m_cache[index].prev=-1; m_cache[index].next = m_freeCacheNodes; m_freeCacheNodes = index; m_count--; }
void pscmSetHint(struct pscmGfx *pscm, char *hint, char *value) /* set a hint */ { if (!value) return; if (sameString(value,"")) { hashRemove(pscm->hints, hint); } struct hashEl *el = hashLookup(pscm->hints, hint); if (el) { freeMem(el->val); el->val = cloneString(value); } else { hashAdd(pscm->hints, hint, cloneString(value)); } }
void rudpFree(struct rudp **pRu) /* Free up rudp. Note this does *not* close the associated socket. */ { struct rudp *ru = *pRu; if (ru->recvHash) { struct dlNode *node; while (!dlEmpty(ru->recvList)) { node = dlPopHead(ru->recvList); struct packetSeen *p = node->val; freeMem(node); hashRemove(ru->recvHash, p->recvHashKey); freePacketSeen(&p); } freeDlList(&ru->recvList); hashFree(&ru->recvHash); } freez(pRu); }
void sweepOutOldPacketsSeen(struct rudp *ru, long now) /* Sweep out old packets seen, we can only remember so many. */ { int period = 8; /* seconds */ struct dlNode *node; struct packetSeen *p; while (TRUE) { if (dlEmpty(ru->recvList)) break; p = ru->recvList->head->val; if (now - p->lastChecked < period) break; --ru->recvCount; node = dlPopHead(ru->recvList); freeMem(node); hashRemove(ru->recvHash, p->recvHashKey); freePacketSeen(&p); } }
void dbTrash(char *db) /* dbTrash - drop tables from a database older than specified N hours. */ { char query[256]; struct sqlResult *sr; char **row; int updateTimeIx; int createTimeIx; int dataLengthIx; int indexLengthIx; int nameIx; int timeIxUsed; unsigned long long totalSize = 0; // expiredTableNames: table exists and is in metaInfo and subject to age limits struct slName *expiredTableNames = NULL; struct slName *lostTables = NULL; // tables existing but not in metaInfo unsigned long long lostTableCount = 0; struct hash *expiredHash = newHash(10); // as determined by metaInfo struct hash *notExpiredHash = newHash(10); struct sqlConnection *conn = sqlConnect(db); if (extFileCheck) checkExtFile(conn); time_t ageSeconds = (time_t)(ageHours * 3600); /* age in seconds */ sqlSafef(query,sizeof(query),"select name,UNIX_TIMESTAMP(lastUse) from %s WHERE " "lastUse < DATE_SUB(NOW(), INTERVAL %ld SECOND);", CT_META_INFO,ageSeconds); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) hashAddInt(expiredHash, row[0], sqlSigned(row[1])); sqlFreeResult(&sr); sqlSafef(query,sizeof(query),"select name,UNIX_TIMESTAMP(lastUse) from %s WHERE " "lastUse >= DATE_SUB(NOW(), INTERVAL %ld SECOND);",CT_META_INFO,ageSeconds); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) hashAddInt(notExpiredHash, row[0], sqlSigned(row[1])); sqlFreeResult(&sr); if (tableStatus) // show table status is very expensive, use only when asked { /* run through the table status business to get table size information */ sqlSafef(query,sizeof(query),"show table status"); STATUS_INIT; while ((row = sqlNextRow(sr)) != NULL) { /* if not doing history too, and this is the history table, next row */ if ((!historyToo) && (sameWord(row[nameIx],"history"))) continue; /* also skip the metaInfo table */ if ((!historyToo) && (sameWord(row[nameIx],CT_META_INFO))) continue; /* don't delete the extFile table */ if (sameWord(row[nameIx],CT_EXTFILE)) continue; SCAN_STATUS; if (hashLookup(expiredHash,row[nameIx])) { slNameAddHead(&expiredTableNames, row[nameIx]); verbose(3,"%s %ld drop %s\n",row[timeIxUsed], (unsigned long)timep, row[nameIx]); /* If sizes are non-NULL, add them up */ if ( ((char *)NULL != row[dataLengthIx]) && ((char *)NULL != row[indexLengthIx]) ) totalSize += sqlLongLong(row[dataLengthIx]) + sqlLongLong(row[indexLengthIx]); hashRemove(expiredHash, row[nameIx]); } else { if (hashLookup(notExpiredHash,row[nameIx])) verbose(3,"%s %ld OK %s\n",row[timeIxUsed], (unsigned long)timep, row[nameIx]); else { /* table exists, but not in metaInfo, is it old enough ? */ if (timep < dropTime) { slNameAddHead(&expiredTableNames, row[nameIx]); verbose(2,"%s %ld dropt %s lost table\n", row[timeIxUsed], (unsigned long)timep, row[nameIx]); /* If sizes are non-NULL, add them up */ if ( ((char *)NULL != row[dataLengthIx]) && ((char *)NULL != row[indexLengthIx]) ) totalSize += sqlLongLong(row[dataLengthIx]) + sqlLongLong(row[indexLengthIx]); } else verbose(3,"%s %ld OKt %s\n",row[timeIxUsed], (unsigned long)timep, row[nameIx]); } } } sqlFreeResult(&sr); } else { // simple 'show tables' is more efficient than 'show table status' sqlSafef(query,sizeof(query),"show tables"); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { if (hashLookup(expiredHash,row[0])) { slNameAddHead(&expiredTableNames, row[0]); time_t lastUse = (time_t)hashIntVal(expiredHash,row[0]); struct tm *lastUseTm = localtime(&lastUse); verbose(3,"%4d-%02d-%02d %02d:%02d:%02d %ld drop %s\n", lastUseTm->tm_year+1900, lastUseTm->tm_mon+1, lastUseTm->tm_mday, lastUseTm->tm_hour, lastUseTm->tm_min, lastUseTm->tm_sec, (unsigned long)lastUse,row[0]); hashRemove(expiredHash, row[0]); } else if (hashLookup(notExpiredHash,row[0])) { time_t lastUse = (time_t)hashIntVal(notExpiredHash,row[0]); struct tm *lastUseTm = localtime(&lastUse); verbose(3,"%4d-%02d-%02d %02d:%02d:%02d %ld OK %s\n", lastUseTm->tm_year+1900, lastUseTm->tm_mon+1, lastUseTm->tm_mday, lastUseTm->tm_hour, lastUseTm->tm_min, lastUseTm->tm_sec, (unsigned long)lastUse,row[0]); } else { struct slName *el = slNameNew(row[0]); slAddHead(&lostTables, el); } } sqlFreeResult(&sr); lostTableCount = slCount(lostTables); // If tables exist, but not in metaInfo, check their age to expire them. // It turns out even this show table status is slow too, so, only // run thru it if asked to eliminate lost tables. It is better to // do this operation with the stand-alone perl script on the customTrash // database machine. if (delLostTable && lostTables) { struct slName *el; for (el = lostTables; el != NULL; el = el->next) { if (sameWord(el->name,"history")) continue; if (sameWord(el->name,CT_META_INFO)) continue; if (sameWord(el->name,CT_EXTFILE)) continue; boolean oneTableOnly = FALSE; // protect against multiple tables /* get table time information to see if it is expired */ sqlSafef(query,sizeof(query),"show table status like '%s'", el->name); STATUS_INIT; while ((row = sqlNextRow(sr)) != NULL) { if (oneTableOnly) errAbort("ERROR: query: '%s' returned more than one table " "name\n", query); else oneTableOnly = TRUE; if (differentWord(row[nameIx], el->name)) errAbort("ERROR: query: '%s' did not return table name '%s' != '%s'\n", query, el->name, row[nameIx]); SCAN_STATUS; if (timep < dropTime) { slNameAddHead(&expiredTableNames, row[nameIx]); verbose(2,"%s %ld dropt %s lost table\n", row[timeIxUsed], (unsigned long)timep, row[nameIx]); } else verbose(3,"%s %ld OKt %s\n", row[timeIxUsed], (unsigned long)timep, row[nameIx]); } sqlFreeResult(&sr); } } } /* perhaps the table was already dropped, but not from the metaInfo */ struct hashEl *elList = hashElListHash(expiredHash); struct hashEl *el; for (el = elList; el != NULL; el = el->next) { verbose(2,"%s exists in %s only\n", el->name, CT_META_INFO); if (drop) ctTouchLastUse(conn, el->name, FALSE); /* removes metaInfo row */ } if (drop) { char comment[256]; if (expiredTableNames) { struct slName *el; int droppedCount = 0; /* customTrash DB user permissions do not have permissions to * drop tables. Must use standard special user that has all * permissions. If we are not using the standard user at this * point, then switch to it. */ if (sameWord(db,CUSTOM_TRASH)) { sqlDisconnect(&conn); conn = sqlConnect(db); } for (el = expiredTableNames; el != NULL; el = el->next) { verbose(2,"# drop %s\n", el->name); sqlDropTable(conn, el->name); ctTouchLastUse(conn, el->name, FALSE); /* removes metaInfo row */ ++droppedCount; } /* add a comment to the history table and finish up connection */ if (tableStatus) safef(comment, sizeof(comment), "Dropped %d tables with " "total size %llu, %llu lost tables", droppedCount, totalSize, lostTableCount); else safef(comment, sizeof(comment), "Dropped %d tables, no size info, %llu lost tables", droppedCount, lostTableCount); verbose(2,"# %s\n", comment); hgHistoryComment(conn, "%s", comment); } else { safef(comment, sizeof(comment), "Dropped no tables, none expired, %llu lost tables", lostTableCount); verbose(2,"# %s\n", comment); } } else { char comment[256]; if (expiredTableNames) { int droppedCount = slCount(expiredTableNames); if (tableStatus) safef(comment, sizeof(comment), "Would have dropped %d tables with " "total size %llu, %llu lost tables", droppedCount, totalSize, lostTableCount); else safef(comment, sizeof(comment), "Would have dropped %d tables, no size info, %llu lost tables", droppedCount, lostTableCount); verbose(2,"# %s\n", comment); } else { safef(comment, sizeof(comment), "Would have dropped no tables, none expired, %llu lost tables", lostTableCount); verbose(2,"# %s\n", comment); } } sqlDisconnect(&conn); }
boolean hashMayRemove(struct hash *hash, char *name) /* Remove item of the given name from hash table, if present. * Return true if it was present */ { return (hashRemove(hash, name) != NULL); }
void extractMafs(char *file, FILE *f, struct hash *regionHash) /* extract MAFs in a file from regions specified in hash */ { char *chrom = NULL; struct bed *bed = NULL; struct mafFile *mf = mafOpen(file); struct mafAli *maf = NULL; struct mafComp *mc; char path[256]; verbose(1, "extracting from %s\n", file); maf = mafNext(mf); while (maf) { mc = maf->components; if (!chrom || differentString(chrom, chromFromSrc(mc->src))) chrom = cloneString(chromFromSrc(mc->src)); /* new chrom */ bed = (struct bed *)hashFindVal(regionHash, chrom); if (!bed) { /* no regions on this chrom -- skip to next chrom */ do mafAliFree(&maf); while (((maf = mafNext(mf)) != NULL) && sameString(chromFromSrc(maf->components->src), chrom)); continue; // start over with this maf } verbose(2, "region: %s:%d-%d\n", bed->chrom, bed->chromStart+1, bed->chromEnd); if (outDir) { if (f) endOutFile(f); safef(path, sizeof (path), "%s/%s.maf", dir, bed->name); f = startOutFile(path); } /* skip mafs before region, stopping if chrom changes */ while (maf && (mc = maf->components) && sameString(chrom, chromFromSrc(mc->src)) && (mc->start + mc->size) <= bed->chromStart) { mafAliFree(&maf); maf = mafNext(mf); } /* extract all mafs and pieces of mafs in region */ while (maf && (mc = maf->components) && sameString(chrom, chromFromSrc(mc->src)) && (bed->chromStart < mc->start + mc->size && bed->chromEnd > mc->start)) { int mafStart = mc->start; int mafEnd = mc->start + mc->size; struct mafAli *full = maf; if (mafStart < bed->chromStart || mafEnd > bed->chromEnd) { full = maf; maf = mafSubsetE(full, mc->src, bed->chromStart, bed->chromEnd, keepInitialGaps); mc = maf->components; } verbose(2, " %s:%d-%d\n", chrom, mc->start+1, mc->start + mc->size); mafWrite(f, maf); struct mafAli *nextMaf = (mafEnd > bed->chromEnd+1) ? mafSubset(full, mc->src, bed->chromEnd+1, mafEnd) : mafNext(mf); if (maf != full) mafAliFree(&maf); mafAliFree(&full); maf = nextMaf; } /* get next region */ hashRemove(regionHash, bed->chrom); if (bed->next) hashAdd(regionHash, bed->chrom, bed->next); } mafFileFree(&mf); }
long processMaf(struct mafAli *maf, struct hash *componentHash, FILE *f, struct mafFile *mf, char *fileName) /* Compute scores for each pairwise component in the maf and output to .tab file */ { struct mafComp *mc = NULL, *nextMc = NULL; struct mafSummary *ms, *msPending; struct mafAli pairMaf; long componentCount = 0; struct mafComp *mcMaster = mafMaster(maf, mf, fileName); struct mafComp *oldMasterNext = mcMaster->next; char *e, *chrom; char src[256]; strcpy(src, mcMaster->src); chrom = chopPrefix(src); for (mc = maf->components; mc != NULL; mc = nextMc) { nextMc = mc->next; if (sameString(mcMaster->src, mc->src) || mc->size == 0) continue; /* create maf summary for this alignment component */ AllocVar(ms); ms->chrom = cloneString(chrom); /* both MAF and BED format define chromStart as 0-based */ ms->chromStart = mcMaster->start; /* BED chromEnd is start+size */ ms->chromEnd = mcMaster->start + mcMaster->size; ms->src = cloneString(mc->src); /* remove trailing components (following initial .) to src name */ if ((e = strchr(ms->src, '.')) != NULL) *e = 0; /* construct pairwise maf for scoring */ ZeroVar(&pairMaf); pairMaf.textSize = maf->textSize; pairMaf.components = mcMaster; mcMaster->next = mc; mc->next = NULL; ms->score = scorePairwise(&pairMaf); ms->leftStatus[0] = mc->leftStatus; ms->rightStatus[0] = mc->rightStatus; /* restore component links to allow memory recovery */ mcMaster->next = oldMasterNext; mc->next = nextMc; /* output to .tab file, or save for merging with another block * if this one is too small */ /* handle pending alignment block for this species, if any */ if ((msPending = (struct mafSummary *) hashFindVal(componentHash, ms->src)) != NULL) { /* there is a pending alignment block */ /* either merge it with the current block, or output it */ if (sameString(ms->chrom, msPending->chrom) && (ms->chromStart+1 - msPending->chromEnd < mergeGap)) { /* merge pending block with current */ ms->score = mergeScores(msPending, ms); ms->chromStart = msPending->chromStart; ms->leftStatus[0] = msPending->leftStatus[0]; ms->rightStatus[0] = ms->rightStatus[0]; } else outputSummary(f, msPending); hashRemove(componentHash, msPending->src); mafSummaryFree(&msPending); } /* handle current alignment block (possibly merged) */ if (ms->chromEnd - ms->chromStart > minSize) { /* current block is big enough to output */ outputSummary(f, ms); mafSummaryFree(&ms); } else hashAdd(componentHash, ms->src, ms); componentCount++; } return componentCount; }
int addBamPaired(const bam1_t *bam, void *data) #endif /* bam_fetch() calls this on each bam alignment retrieved. Translate each bam * into a linkedFeaturesSeries item, and either store it until we find its mate * or add it to tg->items. */ { const bam1_core_t *core = &bam->core; struct bamTrackData *btd = (struct bamTrackData *)data; if (! passesFilters(bam, btd)) return 0; struct linkedFeatures *lf = bamToLf(bam, data); struct track *tg = btd->tg; if (!(core->flag & BAM_FPAIRED) || (core->flag & BAM_FMUNMAP)) { if (lf->start < winEnd && lf->end > winStart) slAddHead(&(tg->items), lfsFromLf(lf)); if ((core->flag & BAM_FMUNMAP) && sameString(btd->colorMode, BAM_COLOR_MODE_GRAY) && sameString(btd->grayMode, BAM_GRAY_MODE_UNPAIRED)) // not properly paired: make it a lighter shade. lf->grayIx -= 4; } else { struct linkedFeatures *lfMate = (struct linkedFeatures *)hashFindVal(btd->pairHash, lf->name); if (lfMate == NULL) { if (core->flag & BAM_FPROPER_PAIR) { // If we know that this is properly paired, but don't have the mate, // make a bogus item off the edge of the window so that if we don't // encounter its mate later, we can at least draw an arrow off the // edge of the window. struct linkedFeatures *stub; // don't link to pair that's not on the same chrom if ((core->mpos < 0) || (core->tid != core->mtid)) { int offscreen; if (lf->orientation > 0) offscreen = max(winEnd, lf->end) + 10; else offscreen = min(winStart, lf->start) - 10; if (offscreen < 0) offscreen = 0; stub = lfStub(offscreen, -lf->orientation); } else { stub = lfStub(core->mpos, -lf->orientation); } lf->next = stub; } else if (sameString(btd->colorMode, BAM_COLOR_MODE_GRAY) && sameString(btd->grayMode, BAM_GRAY_MODE_UNPAIRED)) // not properly paired: make it a lighter shade. lf->grayIx -= 4; hashAdd(btd->pairHash, lf->name, lf); } else { lfMate->next = lf; if (min(lfMate->start, lf->start) < winEnd && max(lfMate->end, lf->end) > winStart) slAddHead(&(tg->items), lfsFromLf(lfMate)); hashRemove(btd->pairHash, lf->name); } } return 0; }
void dbTrash(char *db) /* dbTrash - drop tables from a database older than specified N hours. */ { char query[256]; struct sqlResult *sr; char **row; int updateTimeIx; int createTimeIx; int dataLengthIx; int indexLengthIx; int nameIx; int timeIxUsed; unsigned long long totalSize = 0; struct slName *tableNames = NULL; /* subject to age limits */ struct hash *expiredHash = newHash(10); struct hash *notExpiredHash = newHash(10); struct sqlConnection *conn = sqlConnect(db); if (extFileCheck) checkExtFile(conn); time_t ageSeconds = (time_t)(ageHours * 3600); /* age in seconds */ safef(query,sizeof(query),"select name from %s WHERE " "lastUse < DATE_SUB(NOW(), INTERVAL %ld SECOND);", CT_META_INFO,ageSeconds); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) hashAddInt(expiredHash, row[0], 1); sqlFreeResult(&sr); safef(query,sizeof(query),"select name from %s WHERE " "lastUse >= DATE_SUB(NOW(), INTERVAL %ld SECOND);",CT_META_INFO,ageSeconds); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) hashAddInt(notExpiredHash, row[0], 1); sqlFreeResult(&sr); /* run through the table status business to get table size information */ safef(query,sizeof(query),"show table status"); sr = sqlGetResult(conn, query); nameIx = sqlFieldColumn(sr, "Name"); createTimeIx = sqlFieldColumn(sr, "Create_time"); updateTimeIx = sqlFieldColumn(sr, "Update_time"); dataLengthIx = sqlFieldColumn(sr, "Data_length"); indexLengthIx = sqlFieldColumn(sr, "Index_length"); while ((row = sqlNextRow(sr)) != NULL) { struct tm tm; time_t timep = 0; /* if not doing history too, and this is the history table, next row */ if ((!historyToo) && (sameWord(row[nameIx],"history"))) continue; /* also skip the metaInfo table */ if ((!historyToo) && (sameWord(row[nameIx],CT_META_INFO))) continue; /* don't delete the extFile table */ if (sameWord(row[nameIx],CT_EXTFILE)) continue; /* Update_time is sometimes NULL on MySQL 5 * so if it fails, then check the Create_time */ timeIxUsed = updateTimeIx; if ((row[updateTimeIx] != NULL) && (sscanf(row[updateTimeIx], "%4d-%2d-%2d %2d:%2d:%2d", &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday), &(tm.tm_hour), &(tm.tm_min), &(tm.tm_sec)) != 6) ) { timeIxUsed = createTimeIx; if (sscanf(row[createTimeIx], "%4d-%2d-%2d %2d:%2d:%2d", &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday), &(tm.tm_hour), &(tm.tm_min), &(tm.tm_sec)) != 6) { verbose(2,"%s %s %s\n", row[createTimeIx],row[updateTimeIx],row[nameIx]); errAbort("could not parse date %s or %s on table %s\n", row[createTimeIx], row[updateTimeIx], row[nameIx]); } } tm.tm_year -= 1900; tm.tm_mon -= 1; tm.tm_isdst = -1; /* do not know timezone, figure it out */ timep = mktime(&tm); if (hashLookup(expiredHash,row[nameIx])) { slNameAddHead(&tableNames, row[nameIx]); verbose(3,"%s %ld drop %s\n",row[timeIxUsed], (unsigned long)timep, row[nameIx]); /* If sizes are non-NULL, add them up */ if ( ((char *)NULL != row[dataLengthIx]) && ((char *)NULL != row[indexLengthIx]) ) totalSize += sqlLongLong(row[dataLengthIx]) + sqlLongLong(row[indexLengthIx]); hashRemove(expiredHash, row[nameIx]); } else { if (hashLookup(notExpiredHash,row[nameIx])) verbose(3,"%s %ld OK %s\n",row[timeIxUsed], (unsigned long)timep, row[nameIx]); else { /* table exists, but not in metaInfo, is it old enough ? */ if (timep < dropTime) { slNameAddHead(&tableNames, row[nameIx]); verbose(2,"%s %ld dropt %s\n", row[timeIxUsed], (unsigned long)timep, row[nameIx]); /* If sizes are non-NULL, add them up */ if ( ((char *)NULL != row[dataLengthIx]) && ((char *)NULL != row[indexLengthIx]) ) totalSize += sqlLongLong(row[dataLengthIx]) + sqlLongLong(row[indexLengthIx]); } else verbose(3,"%s %ld OKt %s\n",row[timeIxUsed], (unsigned long)timep, row[nameIx]); } } } sqlFreeResult(&sr); /* perhaps the table was already dropped, but not from the metaInfo */ struct hashEl *elList = hashElListHash(expiredHash); struct hashEl *el; for (el = elList; el != NULL; el = el->next) { verbose(2,"%s exists in %s only\n", el->name, CT_META_INFO); if (drop) ctTouchLastUse(conn, el->name, FALSE); /* removes metaInfo row */ } if (drop) { if (tableNames) { char comment[256]; struct slName *el; int droppedCount = 0; /* customTrash DB user permissions do not have permissions to * drop tables. Must use standard special user that has all * permissions. If we are not using the standard user at this * point, then switch to it. */ if (sameWord(db,CUSTOM_TRASH)) { sqlDisconnect(&conn); conn = sqlConnect(db); } for (el = tableNames; el != NULL; el = el->next) { verbose(2,"# drop %s\n", el->name); sqlDropTable(conn, el->name); ctTouchLastUse(conn, el->name, FALSE); /* removes metaInfo row */ ++droppedCount; } /* add a comment to the history table and finish up connection */ safef(comment, sizeof(comment), "Dropped %d tables with total size %llu", droppedCount, totalSize); verbose(2,"# %s\n", comment); hgHistoryComment(conn, comment); } } sqlDisconnect(&conn); }