[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59497] trunk/blender/source/blender: clearing the mempool can now keep more then a single element reserved.
Campbell Barton
ideasman42 at gmail.com
Sun Aug 25 18:16:38 CEST 2013
Revision: 59497
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59497
Author: campbellbarton
Date: 2013-08-25 16:16:38 +0000 (Sun, 25 Aug 2013)
Log Message:
-----------
clearing the mempool can now keep more then a single element reserved.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/treehash.c
trunk/blender/source/blender/blenlib/BLI_ghash.h
trunk/blender/source/blender/blenlib/BLI_mempool.h
trunk/blender/source/blender/blenlib/intern/BLI_ghash.c
trunk/blender/source/blender/blenlib/intern/BLI_mempool.c
trunk/blender/source/blender/blenlib/intern/edgehash.c
Modified: trunk/blender/source/blender/blenkernel/intern/treehash.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/treehash.c 2013-08-25 14:58:26 UTC (rev 59496)
+++ trunk/blender/source/blender/blenkernel/intern/treehash.c 2013-08-25 16:16:38 UTC (rev 59497)
@@ -113,7 +113,7 @@
void *BKE_treehash_rebuild_from_treestore(void *treehash, BLI_mempool *treestore)
{
- BLI_ghash_clear(treehash, NULL, free_treehash_group);
+ BLI_ghash_clear_ex(treehash, NULL, free_treehash_group, BLI_mempool_count(treestore));
fill_treehash(treehash, treestore);
return treehash;
}
Modified: trunk/blender/source/blender/blenlib/BLI_ghash.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_ghash.h 2013-08-25 14:58:26 UTC (rev 59496)
+++ trunk/blender/source/blender/blenlib/BLI_ghash.h 2013-08-25 16:16:38 UTC (rev 59497)
@@ -68,6 +68,8 @@
void **BLI_ghash_lookup_p(GHash *gh, const void *key);
bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
+void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp,
+ const unsigned int nentries_reserve);
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
bool BLI_ghash_haskey(GHash *gh, const void *key);
int BLI_ghash_size(GHash *gh);
Modified: trunk/blender/source/blender/blenlib/BLI_mempool.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_mempool.h 2013-08-25 14:58:26 UTC (rev 59496)
+++ trunk/blender/source/blender/blenlib/BLI_mempool.h 2013-08-25 16:16:38 UTC (rev 59497)
@@ -73,6 +73,12 @@
__attribute__((nonnull(1, 2)))
#endif
;
+void BLI_mempool_clear_ex(BLI_mempool *pool,
+ const int totelem_reserve)
+#ifdef __GNUC__
+__attribute__((nonnull(1)))
+#endif
+;
void BLI_mempool_clear(BLI_mempool *pool)
#ifdef __GNUC__
__attribute__((nonnull(1)))
Modified: trunk/blender/source/blender/blenlib/intern/BLI_ghash.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/BLI_ghash.c 2013-08-25 14:58:26 UTC (rev 59496)
+++ trunk/blender/source/blender/blenlib/intern/BLI_ghash.c 2013-08-25 16:16:38 UTC (rev 59497)
@@ -96,6 +96,16 @@
}
/**
+ * Increase initial bucket size to match a reserved ammount.
+ */
+BLI_INLINE void ghash_buckets_reserve(GHash *gh, const unsigned int nentries_reserve)
+{
+ while (ghash_test_expand_buckets(nentries_reserve, gh->nbuckets)) {
+ gh->nbuckets = hashsizes[++gh->cursize];
+ }
+}
+
+/**
* Get the hash for a key.
*/
BLI_INLINE unsigned int ghash_keyhash(GHash *gh, const void *key)
@@ -197,9 +207,7 @@
/* if we have reserved the number of elements that this hash will contain */
if (nentries_reserve) {
- while (ghash_test_expand_buckets(nentries_reserve, gh->nbuckets)) {
- gh->nbuckets = hashsizes[++gh->cursize];
- }
+ ghash_buckets_reserve(gh, nentries_reserve);
}
gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
@@ -375,8 +383,10 @@
*
* \param keyfreefp Optional callback to free the key.
* \param valfreefp Optional callback to free the value.
+ * \param nentries_reserve Optionally reserve the number of members that the hash will hold.
*/
-void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
+void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp,
+ const unsigned int nentries_reserve)
{
unsigned int i;
@@ -395,17 +405,29 @@
}
}
+ gh->nbuckets = hashsizes[0]; /* gh->cursize */
+ gh->nentries = 0;
gh->cursize = 0;
- gh->nentries = 0;
- gh->nbuckets = hashsizes[gh->cursize];
+ if (nentries_reserve) {
+ ghash_buckets_reserve(gh, nentries_reserve);
+ }
+
MEM_freeN(gh->buckets);
gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
- BLI_mempool_clear(gh->entrypool);
+ BLI_mempool_clear_ex(gh->entrypool, nentries_reserve ? (int)nentries_reserve : -1);
}
/**
+ * Wraps #BLI_ghash_clear_ex with zero entries reserved.
+ */
+void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
+{
+ BLI_ghash_clear_ex(gh, keyfreefp, valfreefp, 0);
+}
+
+/**
* Frees the GHash and its members.
*
* \param gh The GHash to free.
Modified: trunk/blender/source/blender/blenlib/intern/BLI_mempool.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/BLI_mempool.c 2013-08-25 14:58:26 UTC (rev 59496)
+++ trunk/blender/source/blender/blenlib/intern/BLI_mempool.c 2013-08-25 16:16:38 UTC (rev 59497)
@@ -87,6 +87,7 @@
/* keeps aligned to 16 bits */
BLI_freenode *free; /* free element list. Interleaved into chunk datas. */
+ int maxchunks; /* use to know how many chunks to keep for BLI_mempool_clear */
int totused; /* number of elements currently in use */
#ifdef USE_TOTALLOC
int totalloc; /* number of elements allocated in total */
@@ -101,6 +102,14 @@
# define CHUNK_DATA(chunk) (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))
#endif
+/**
+ * \return the number of chunks to allocate based on how many elements are needed.
+ */
+BLI_INLINE int mempool_maxchunks(const int totelem, const int pchunk)
+{
+ return totelem / pchunk + 1;
+}
+
static BLI_mempool_chunk *mempool_chunk_alloc(BLI_mempool *pool)
{
BLI_mempool_chunk *mpchunk;
@@ -183,35 +192,37 @@
return curnode;
}
-static void mempool_chunk_free_all(BLI_mempool *pool)
+static void mempool_chunk_free(BLI_mempool_chunk *mpchunk, const int flag)
{
- BLI_mempool_chunk *mpchunk, *mpchunk_next;
-
- if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
- for (mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk_next) {
- mpchunk_next = mpchunk->next;
+ if (flag & BLI_MEMPOOL_SYSMALLOC) {
#ifdef USE_DATA_PTR
- free(CHUNK_DATA(mpchunk));
+ free(CHUNK_DATA(mpchunk));
#endif
- free(mpchunk);
- }
+ free(mpchunk);
}
else {
- for (mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk_next) {
- mpchunk_next = mpchunk->next;
#ifdef USE_DATA_PTR
- MEM_freeN(CHUNK_DATA(mpchunk));
+ MEM_freeN(CHUNK_DATA(mpchunk));
#endif
- MEM_freeN(mpchunk);
- }
+ MEM_freeN(mpchunk);
}
- pool->chunks.first = pool->chunks.last = NULL;
}
+static void mempool_chunk_free_all(ListBase *chunks, const int flag)
+{
+ BLI_mempool_chunk *mpchunk, *mpchunk_next;
+
+ for (mpchunk = chunks->first; mpchunk; mpchunk = mpchunk_next) {
+ mpchunk_next = mpchunk->next;
+ mempool_chunk_free(mpchunk, flag);
+ }
+ chunks->first = chunks->last = NULL;
+}
+
BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag)
{
BLI_mempool *pool = NULL;
- BLI_freenode *lasttail = NULL, *curnode = NULL;
+ BLI_freenode *lasttail = NULL;
int i, maxchunks;
/* allocate the pool structure */
@@ -234,29 +245,23 @@
pool->esize = esize;
}
+ maxchunks = mempool_maxchunks(totelem, pchunk);
+
pool->flag = flag;
pool->pchunk = pchunk;
pool->csize = esize * pchunk;
pool->chunks.first = pool->chunks.last = NULL;
pool->free = NULL; /* mempool_chunk_add assigns */
+ pool->maxchunks = maxchunks;
#ifdef USE_TOTALLOC
pool->totalloc = 0;
#endif
pool->totused = 0;
- maxchunks = totelem / pchunk + 1;
- if (maxchunks == 0) {
- maxchunks = 1;
- }
-
/* allocate the actual chunks */
for (i = 0; i < maxchunks; i++) {
BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
-
- curnode = mempool_chunk_add(pool, mpchunk, lasttail);
-
- /* set the end of this chunks memory to the new tail for next iteration */
- lasttail = curnode;
+ lasttail = mempool_chunk_add(pool, mpchunk, lasttail);
}
return pool;
@@ -338,7 +343,7 @@
BLI_mempool_chunk *first = pool->chunks.first;
BLI_remlink(&pool->chunks, first);
- mempool_chunk_free_all(pool);
+ mempool_chunk_free_all(&pool->chunks, pool->flag);
BLI_addtail(&pool->chunks, first);
#ifdef USE_TOTALLOC
pool->totalloc = pool->pchunk;
@@ -504,30 +509,57 @@
#endif
-void BLI_mempool_clear(BLI_mempool *pool)
+void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
{
- BLI_mempool_chunk *first = pool->chunks.first;
+ BLI_mempool_chunk *mpchunk;
+ BLI_mempool_chunk *mpchunk_next;
+ int maxchunks;
- BLI_remlink(&pool->chunks, first);
+ ListBase chunks_temp;
+ BLI_freenode *lasttail = NULL;
- mempool_chunk_free_all(pool);
+ if (totelem_reserve == -1) {
+ maxchunks = pool->maxchunks;
+ }
+ else {
+ maxchunks = mempool_maxchunks(totelem_reserve, pool->pchunk);
+ }
- /* important for re-initializing */
+ /* free all after pool->maxchunks */
+
+ for (mpchunk = BLI_findlink(&pool->chunks, maxchunks); mpchunk; mpchunk = mpchunk_next) {
+ mpchunk_next = mpchunk->next;
+ BLI_remlink(&pool->chunks, mpchunk);
+ mempool_chunk_free(mpchunk, pool->flag);
+ }
+
+ /* re-initialize */
+ pool->free = NULL;
pool->totused = 0;
#ifdef USE_TOTALLOC
pool->totalloc = 0;
#endif
- pool->free = NULL;
- mempool_chunk_add(pool, first, NULL);
+ chunks_temp = pool->chunks;
+ pool->chunks.first = pool->chunks.last = NULL;
+
+ while ((mpchunk = chunks_temp.first)) {
+ BLI_remlink(&chunks_temp, mpchunk);
+ lasttail = mempool_chunk_add(pool, mpchunk, lasttail);
+ }
}
+void BLI_mempool_clear(BLI_mempool *pool)
+{
+ return BLI_mempool_clear_ex(pool, -1);
+}
+
/**
* Free the mempool its self (and all elements).
*/
void BLI_mempool_destroy(BLI_mempool *pool)
{
- mempool_chunk_free_all(pool);
+ mempool_chunk_free_all(&pool->chunks, pool->flag);
if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
free(pool);
Modified: trunk/blender/source/blender/blenlib/intern/edgehash.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/edgehash.c 2013-08-25 14:58:26 UTC (rev 59496)
+++ trunk/blender/source/blender/blenlib/intern/edgehash.c 2013-08-25 16:16:38 UTC (rev 59497)
@@ -90,6 +90,16 @@
return (nentries > nbuckets * 3);
}
+/**
+ * Increase initial bucket size to match a reserved ammount.
+ */
+BLI_INLINE void edgehash_buckets_reserve(EdgeHash *eh, const unsigned int nentries_reserve)
+{
+ while (edgehash_test_expand_buckets(nentries_reserve, eh->nbuckets)) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list