[med-svn] [htslib] 05/13: Free all in-flight pileups in bam_plp_destroy()

Andreas Tille tille at debian.org
Sat Jan 30 13:23:56 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository htslib.

commit df4a80e9c387bb1d84cdb47c02e44e77b0f57770
Author: John Marshall <jm18 at sanger.ac.uk>
Date:   Tue Nov 17 10:50:40 2015 +0000

    Free all in-flight pileups in bam_plp_destroy()
    
    Fixes #299.
    
    Write bam_plp_next()'s node-deleting loop more clearly, using a pointer
    to the pointer-that-points-to-the-node rather than an obscurely-used
    dummy node.  Write list-is-empty tests more clearly.  Lift the call to
    overlap_remove() out of the loop in bam_plp_reset(), as it is idempotent.
---
 sam.c | 55 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 28 insertions(+), 27 deletions(-)

diff --git a/sam.c b/sam.c
index a637aa4..65c8fd7 100644
--- a/sam.c
+++ b/sam.c
@@ -1,6 +1,6 @@
 /*  sam.c -- SAM and BAM file I/O and manipulation.
 
-    Copyright (C) 2008-2010, 2012-2014 Genome Research Ltd.
+    Copyright (C) 2008-2010, 2012-2016 Genome Research Ltd.
     Copyright (C) 2010, 2012, 2013 Broad Institute.
 
     Author: Heng Li <lh3 at sanger.ac.uk>
@@ -1599,7 +1599,7 @@ typedef khash_t(olap_hash) olap_hash_t;
 
 struct __bam_plp_t {
     mempool_t *mp;
-    lbnode_t *head, *tail, *dummy;
+    lbnode_t *head, *tail;
     int32_t tid, pos, max_tid, max_pos;
     int is_eof, max_plp, error, maxcnt;
     uint64_t id;
@@ -1617,7 +1617,6 @@ bam_plp_t bam_plp_init(bam_plp_auto_f func, void *data)
     iter = (bam_plp_t)calloc(1, sizeof(struct __bam_plp_t));
     iter->mp = mp_init();
     iter->head = iter->tail = mp_alloc(iter->mp);
-    iter->dummy = mp_alloc(iter->mp);
     iter->max_tid = iter->max_pos = -1;
     iter->maxcnt = 8000;
     if (func) {
@@ -1635,11 +1634,12 @@ void bam_plp_init_overlaps(bam_plp_t iter)
 
 void bam_plp_destroy(bam_plp_t iter)
 {
+    lbnode_t *p, *pnext;
     if ( iter->overlaps ) kh_destroy(olap_hash, iter->overlaps);
-    mp_free(iter->mp, iter->dummy);
-    mp_free(iter->mp, iter->head);
-    if (iter->mp->cnt != 0)
-        fprintf(stderr, "[bam_plp_destroy] memory leak: %d. Continue anyway.\n", iter->mp->cnt);
+    for (p = iter->head; p != NULL; p = pnext) {
+        pnext = p->next;
+        mp_free(iter->mp, p);
+    }
     mp_destroy(iter->mp);
     if (iter->b) bam_destroy1(iter->b);
     free(iter->plp);
@@ -1854,29 +1854,32 @@ const bam_pileup1_t *bam_plp_next(bam_plp_t iter, int *_tid, int *_pos, int *_n_
 {
     if (iter->error) { *_n_plp = -1; return 0; }
     *_n_plp = 0;
-    if (iter->is_eof && iter->head->next == 0) return 0;
+    if (iter->is_eof && iter->head == iter->tail) return 0;
     while (iter->is_eof || iter->max_tid > iter->tid || (iter->max_tid == iter->tid && iter->max_pos > iter->pos)) {
         int n_plp = 0;
-        lbnode_t *p, *q;
         // write iter->plp at iter->pos
-        iter->dummy->next = iter->head;
-        for (p = iter->head, q = iter->dummy; p->next; q = p, p = p->next) {
+        lbnode_t **pptr = &iter->head;
+        while (*pptr != iter->tail) {
+            lbnode_t *p = *pptr;
             if (p->b.core.tid < iter->tid || (p->b.core.tid == iter->tid && p->end <= iter->pos)) { // then remove
                 overlap_remove(iter, &p->b);
-                q->next = p->next; mp_free(iter->mp, p); p = q;
-            } else if (p->b.core.tid == iter->tid && p->beg <= iter->pos) { // here: p->end > pos; then add to pileup
-                if (n_plp == iter->max_plp) { // then double the capacity
-                    iter->max_plp = iter->max_plp? iter->max_plp<<1 : 256;
-                    iter->plp = (bam_pileup1_t*)realloc(iter->plp, sizeof(bam_pileup1_t) * iter->max_plp);
+                *pptr = p->next; mp_free(iter->mp, p);
+            }
+            else {
+                if (p->b.core.tid == iter->tid && p->beg <= iter->pos) { // here: p->end > pos; then add to pileup
+                    if (n_plp == iter->max_plp) { // then double the capacity
+                        iter->max_plp = iter->max_plp? iter->max_plp<<1 : 256;
+                        iter->plp = (bam_pileup1_t*)realloc(iter->plp, sizeof(bam_pileup1_t) * iter->max_plp);
+                    }
+                    iter->plp[n_plp].b = &p->b;
+                    if (resolve_cigar2(iter->plp + n_plp, iter->pos, &p->s)) ++n_plp; // actually always true...
                 }
-                iter->plp[n_plp].b = &p->b;
-                if (resolve_cigar2(iter->plp + n_plp, iter->pos, &p->s)) ++n_plp; // actually always true...
+                pptr = &(*pptr)->next;
             }
         }
-        iter->head = iter->dummy->next; // dummy->next may be changed
         *_n_plp = n_plp; *_tid = iter->tid; *_pos = iter->pos;
         // update iter->tid and iter->pos
-        if (iter->head->next) {
+        if (iter->head != iter->tail) {
             if (iter->tid > iter->head->b.core.tid) {
                 fprintf(stderr, "[%s] unsorted input. Pileup aborts.\n", __func__);
                 iter->error = 1;
@@ -1891,7 +1894,7 @@ const bam_pileup1_t *bam_plp_next(bam_plp_t iter, int *_tid, int *_pos, int *_n_
         } else ++iter->pos; // scan contiguously
         // return
         if (n_plp) return iter->plp;
-        if (iter->is_eof && iter->head->next == 0) break;
+        if (iter->is_eof && iter->head == iter->tail) break;
     }
     return 0;
 }
@@ -1961,17 +1964,15 @@ const bam_pileup1_t *bam_plp_auto(bam_plp_t iter, int *_tid, int *_pos, int *_n_
 
 void bam_plp_reset(bam_plp_t iter)
 {
-    lbnode_t *p, *q;
+    overlap_remove(iter, NULL);
     iter->max_tid = iter->max_pos = -1;
     iter->tid = iter->pos = 0;
     iter->is_eof = 0;
-    for (p = iter->head; p->next;) {
-        overlap_remove(iter, NULL);
-        q = p->next;
+    while (iter->head != iter->tail) {
+        lbnode_t *p = iter->head;
+        iter->head = p->next;
         mp_free(iter->mp, p);
-        p = q;
     }
-    iter->head = iter->tail;
 }
 
 void bam_plp_set_maxcnt(bam_plp_t iter, int maxcnt)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/htslib.git



More information about the debian-med-commit mailing list