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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to