2843d2cfc55054140b354bc75ad25f1eacbfda30 braney Wed Jan 15 23:19:30 2020 -0800 Revert "hgCollection fiddles with the settingsHash of trackDb, which might be" This reverts commit 3e29ad0059ebf3c9b781ac5317e692ae2a2687bb. diff --git src/lib/localmem.c src/lib/localmem.c index 4d8b0d9..7030a53 100644 --- src/lib/localmem.c +++ src/lib/localmem.c @@ -1,330 +1,293 @@ /* LocalMem.c - local memory routines. * * These routines are meant for the sort of scenario where * a lot of little to medium size pieces of memory are * allocated, and then disposed of all at once. * * This file is copyright 2002 Jim Kent, but license is hereby * granted for all use - public, private or commercial. */ #include "common.h" -#include "hash.h" #include "localmem.h" struct lm { struct lmBlock *blocks; size_t blockSize; size_t allignMask; size_t allignAdd; boolean doMemoryAllocs; // if true, do our own memory allocs, otherwise use passed in pointer }; struct lmBlock { struct lmBlock *next; char *free; char *end; char *extra; }; static struct lmBlock *newBlock(struct lm *lm, size_t reqSize) /* Allocate a new block of at least reqSize */ { size_t size = (reqSize > lm->blockSize ? reqSize : lm->blockSize); size_t fullSize = size + sizeof(struct lmBlock); struct lmBlock *mb = needLargeZeroedMem(fullSize); if (mb == NULL) errAbort("Couldn't allocate %lld bytes", (long long)fullSize); mb->free = (char *)(mb+1); mb->end = ((char *)mb) + fullSize; mb->next = lm->blocks; lm->blocks = mb; return mb; } struct lm *lmGuts(int blockSize, void *mem) /* Create a local memory pool. */ { struct lm *lm; int aliSize = sizeof(long); if (aliSize < sizeof(double)) aliSize = sizeof(double); if (aliSize < sizeof(void *)) aliSize = sizeof(void *); lm = needMem(sizeof(*lm)); lm->blocks = NULL; if (blockSize <= 0) blockSize = (1<<14); /* 16k default. */ lm->blockSize = blockSize; lm->allignAdd = (aliSize-1); lm->allignMask = ~lm->allignAdd; if (mem != NULL) { lm->doMemoryAllocs = FALSE; struct lmBlock *mb = mem; mb->free = (char *)(mb+1); mb->end = ((char *)mb) + blockSize; mb->next = lm->blocks; lm->blocks = mb; } else { lm->doMemoryAllocs = TRUE; newBlock(lm, blockSize); } return lm; } struct lm *lmInit(int blockSize) /* Create a local memory pool. */ { return lmGuts(blockSize, NULL); } struct lm *lmInitWMem(void *mem, int blockSize) /* Create a local memory pool. */ { return lmGuts(blockSize, mem); } void lmCleanup(struct lm **pLm) /* Clean up a local memory pool. */ { struct lm *lm = *pLm; if (lm == NULL) return; *pLm = NULL; slFreeList(&lm->blocks); freeMem(lm); } unsigned int lmBlockHeaderSize() // Return the size of an lmBlock. { return sizeof(struct lmBlock); } size_t lmUsed(struct lm *lm) // Returns amount of memory allocated { size_t used = 0; struct lmBlock *mb = lm->blocks; for (;mb != NULL;mb = mb->next) used += (mb->free - (char *)(mb+1)); return used; } size_t lmAvailable(struct lm *lm) // Returns currently available memory in pool { struct lmBlock *mb = lm->blocks; return (mb->end - mb->free); } size_t lmSize(struct lm *lm) // Returns current size of pool, even for memory already allocated { size_t fullSize = 0; struct lmBlock *mb = lm->blocks; for (;mb != NULL;mb = mb->next) fullSize += (mb->end - (char *)(mb+1)); return fullSize; } void *lmAlloc(struct lm *lm, size_t size) /* Allocate memory from local pool. */ { struct lmBlock *mb = lm->blocks; void *ret; size_t memLeft = mb->end - mb->free; if (memLeft < size) { if (lm->doMemoryAllocs) mb = newBlock(lm, size); else errAbort("attempted local memory alloc in fixed size allocator"); } ret = mb->free; mb->free += ((size+lm->allignAdd)&lm->allignMask); if (mb->free > mb->end) mb->free = mb->end; return ret; } void *lmAllocMoreMem(struct lm *lm, void *pt, size_t oldSize, size_t newSize) /* Adjust memory size on a block, possibly relocating it. If block is grown, * new memory is zeroed. */ { struct lmBlock *mb = lm->blocks; // rare case that pointer is to last lm alloc, but still try. // Note this is the one place where the pointer gets reused and it is known to be in this lm if ((char *)pt + oldSize == mb->free && (char *)pt + newSize <= mb->end) { if (newSize > oldSize) // only move the free pointer on more mem mb->free = pt + newSize; return pt; } void *new = lmAlloc(lm, newSize); memcpy(new, pt, oldSize); return new; } void *lmCloneMem(struct lm *lm, void *pt, size_t size) /* Return a local mem copy of memory block. */ { void *d = lmAlloc(lm, size); memcpy(d, pt, size); return d; } char *lmCloneStringZ(struct lm *lm, const char *string, int size) /* Return local mem copy of string. */ { if (string == NULL) return NULL; else { char *s = lmAlloc(lm, size+1); memcpy(s, string, size); return s; } } char *lmCloneString(struct lm *lm, const char *string) /* Return local mem copy of string. */ { if (string == NULL) return NULL; else return lmCloneStringZ(lm, string, strlen(string)); } char *lmCloneFirstWord(struct lm *lm, const char *line) /* Clone first word in line */ { char *startFirstWord = skipLeadingSpaces(line); if (startFirstWord == NULL) return NULL; char *endFirstWord = skipToSpaces(startFirstWord); if (endFirstWord == NULL) return lmCloneString(lm, startFirstWord); else return lmCloneStringZ(lm, startFirstWord, endFirstWord - startFirstWord); } char *lmCloneSomeWord(struct lm *lm, const char *line, int wordIx) /* Return a clone of the given space-delimited word within line. Returns NULL if * not that many words in line. */ { if (wordIx < 0) return NULL; int i; for (i=0; i<wordIx; ++i) { line = skipLeadingSpaces(line); line = skipToSpaces(line); if (line == NULL) return NULL; } return lmCloneFirstWord(lm, line); } struct slName *lmSlName(struct lm *lm, const char *name) /* Return slName in memory. */ { struct slName *n; int size = sizeof(*n) + strlen(name) + 1; n = lmAlloc(lm, size); strcpy(n->name, name); return n; } char **lmCloneRowExt(struct lm *lm, char **row, int rowOutSize, int rowInSize) /* Allocate an array of strings with rowOutSize elements. Clone the first rowInSize elements * of row into the new array, leaving others NULL if rowOutSize is greater than rowInSize. * rowOutSize must be greater than or equal to rowInSize. */ { if (rowOutSize < rowInSize) errAbort("lmCloneRowExt: rowOutSize (%d) must be greater than or equal to rowInSize (%d)", rowOutSize, rowInSize); char **rowClone = NULL; lmAllocArray(lm, rowClone, rowOutSize); int i; for (i = 0; i < rowInSize; i++) rowClone[i] = lmCloneString(lm, row[i]); return rowClone; } char **lmCloneRow(struct lm *lm, char **row, int rowSize) /* Allocate an array of strings and its contents cloned from row. */ { return lmCloneRowExt(lm, row, rowSize, rowSize); } void lmRefAdd(struct lm *lm, struct slRef **pRefList, void *val) /* Add reference to list. */ { struct slRef *ref; lmAllocVar(lm, ref); ref->val = val; slAddHead(pRefList, ref); } char *lmJoinStrings(struct lm *lm, char *a, char *b) /* Return concatenation of a and b allocated in lm */ { int aSize = strlen(a); int resSize = aSize + strlen(b) + 1; char *output = lmAlloc(lm, resSize); strcpy(output, a); strcpy(output + aSize, b); return output; } -static struct hashEl *lmCloneHashElList(struct lm *lm, struct hashEl *list) -/* Clone a list of hashEl's. */ -{ -struct hashEl *newList = NULL; - -for(; list; list = list->next) - { - struct hashEl *hel = lmAlloc(lm, sizeof(struct hashEl)); - slAddHead(&newList, hel); - hel->name = lmCloneString(lm, list->name); - hel->val = lmCloneString(lm, (char *)list->val); // we're assuming that the values are strings - hel->hashVal = list->hashVal; - } - -return newList; -} - -struct hash *lmCloneHash(struct lm *lm, struct hash *hash) -/* Clone a hash into local memory. ASSUMES VALUES ARE STRINGS */ -{ -struct hash *newHash = lmAlloc(lm, sizeof(struct hash)); - -*newHash = *hash; -newHash->lm = lm; -newHash->ownLm = TRUE; -newHash->next = NULL; -lmAllocArray(lm, newHash->table, hash->size); - -int ii; -for(ii=0; ii < hash->size; ii++) - if (hash->table[ii] != NULL) - newHash->table[ii] = lmCloneHashElList(lm, hash->table[ii]); - -return newHash; -} -