mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
Correctly patch the memory leak related to the apatsequence
This commit is contained in:
@ -11,11 +11,14 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _MaxPatLen = int(C.MAX_PAT_LEN)
|
var _MaxPatLen = int(C.MAX_PAT_LEN)
|
||||||
var _AllocatedApaSequences = 0
|
|
||||||
|
// var _AllocatedApaSequences = int64(0)
|
||||||
var _AllocatedApaPattern = 0
|
var _AllocatedApaPattern = 0
|
||||||
|
|
||||||
// ApatPattern stores a regular pattern usable by the
|
// ApatPattern stores a regular pattern usable by the
|
||||||
@ -155,31 +158,45 @@ func (pattern ApatPattern) Print() {
|
|||||||
func MakeApatSequence(sequence *obiseq.BioSequence, circular bool, recycle ...ApatSequence) (ApatSequence, error) {
|
func MakeApatSequence(sequence *obiseq.BioSequence, circular bool, recycle ...ApatSequence) (ApatSequence, error) {
|
||||||
var errno C.int32_t
|
var errno C.int32_t
|
||||||
var errmsg *C.char
|
var errmsg *C.char
|
||||||
|
var p unsafe.Pointer
|
||||||
seqlen := sequence.Length()
|
seqlen := sequence.Length()
|
||||||
p := C.malloc(C.size_t(seqlen) + 1)
|
|
||||||
|
|
||||||
if p != nil {
|
|
||||||
_AllocatedApaSequences++
|
|
||||||
}
|
|
||||||
|
|
||||||
ic := 0
|
ic := 0
|
||||||
if circular {
|
if circular {
|
||||||
ic = 1
|
ic = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the data into the buffer, by converting it to a Go array
|
|
||||||
cBuf := (*[1 << 31]byte)(p)
|
|
||||||
copy(cBuf[:], sequence.Sequence())
|
|
||||||
cBuf[sequence.Length()] = 0
|
|
||||||
|
|
||||||
var out *C.Seq
|
var out *C.Seq
|
||||||
|
|
||||||
if len(recycle) > 0 {
|
if len(recycle) > 0 {
|
||||||
out = recycle[0].pointer.pointer
|
out = recycle[0].pointer.pointer
|
||||||
|
if (int(out.seqlen) < seqlen || int(out.seqlen) > 5*seqlen) && out.cseq != nil {
|
||||||
|
C.free(unsafe.Pointer(out.cseq))
|
||||||
|
out.cseq = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
out = nil
|
out = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if out == nil || out.cseq == nil {
|
||||||
|
|
||||||
|
p = C.malloc(C.size_t(seqlen) + 1)
|
||||||
|
// if p != nil {
|
||||||
|
// // atomic.AddInt64(&_AllocatedApaSequences, 1)
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
p = unsafe.Pointer(out.cseq)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p == nil {
|
||||||
|
log.Panicln("Cannot allocate memory chunk for Cseq Apat sequecence")
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the data into the buffer, by converting it to a Go array
|
||||||
|
cBuf := (*[1 << 31]byte)(p)
|
||||||
|
copy(cBuf[:], sequence.Sequence())
|
||||||
|
cBuf[sequence.Length()] = 0
|
||||||
|
|
||||||
pseqc := C.new_apatseq((*C.char)(p), C.int32_t(ic), C.int32_t(seqlen),
|
pseqc := C.new_apatseq((*C.char)(p), C.int32_t(ic), C.int32_t(seqlen),
|
||||||
(*C.Seq)(out),
|
(*C.Seq)(out),
|
||||||
&errno, &errmsg)
|
&errno, &errmsg)
|
||||||
@ -187,6 +204,10 @@ func MakeApatSequence(sequence *obiseq.BioSequence, circular bool, recycle ...Ap
|
|||||||
if pseqc == nil {
|
if pseqc == nil {
|
||||||
message := C.GoString(errmsg)
|
message := C.GoString(errmsg)
|
||||||
C.free(unsafe.Pointer(errmsg))
|
C.free(unsafe.Pointer(errmsg))
|
||||||
|
if p != nil {
|
||||||
|
C.free(p)
|
||||||
|
// atomic.AddInt64(&_AllocatedApaSequences, -1)
|
||||||
|
}
|
||||||
return NilApatSequence, errors.New(message)
|
return NilApatSequence, errors.New(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,15 +215,18 @@ func MakeApatSequence(sequence *obiseq.BioSequence, circular bool, recycle ...Ap
|
|||||||
// log.Printf("Make ApatSeq called on %p -> %p\n", out, pseqc)
|
// log.Printf("Make ApatSeq called on %p -> %p\n", out, pseqc)
|
||||||
seq := _ApatSequence{pointer: pseqc}
|
seq := _ApatSequence{pointer: pseqc}
|
||||||
|
|
||||||
runtime.SetFinalizer(&seq, func(p *_ApatSequence) {
|
runtime.SetFinalizer(&seq, func(apat_p *_ApatSequence) {
|
||||||
var errno C.int32_t
|
var errno C.int32_t
|
||||||
var errmsg *C.char
|
var errmsg *C.char
|
||||||
// log.Printf("Finaliser called on %p\n", p.pointer)
|
// log.Printf("Finaliser called on %p\n", apat_p.pointer)
|
||||||
|
|
||||||
if p != nil && p.pointer != nil {
|
if apat_p != nil && apat_p.pointer != nil {
|
||||||
C.free(unsafe.Pointer(p.pointer.cseq))
|
if apat_p.pointer.cseq != nil {
|
||||||
C.delete_apatseq(p.pointer, &errno, &errmsg)
|
C.free(unsafe.Pointer(apat_p.pointer.cseq))
|
||||||
_AllocatedApaSequences--
|
apat_p.pointer.cseq = nil
|
||||||
|
// atomic.AddInt64(&_AllocatedApaSequences, -1)
|
||||||
|
}
|
||||||
|
C.delete_apatseq(apat_p.pointer, &errno, &errmsg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -230,7 +254,13 @@ func (sequence ApatSequence) Free() {
|
|||||||
// log.Printf("Free called on %p\n", sequence.pointer.pointer)
|
// log.Printf("Free called on %p\n", sequence.pointer.pointer)
|
||||||
|
|
||||||
if sequence.pointer != nil && sequence.pointer.pointer != nil {
|
if sequence.pointer != nil && sequence.pointer.pointer != nil {
|
||||||
C.free(unsafe.Pointer(&sequence.pointer.pointer.cseq))
|
|
||||||
|
if sequence.pointer.pointer.cseq != nil {
|
||||||
|
C.free(unsafe.Pointer(sequence.pointer.pointer.cseq))
|
||||||
|
sequence.pointer.pointer.cseq = nil
|
||||||
|
// atomic.AddInt64(&_AllocatedApaSequences, -1)
|
||||||
|
}
|
||||||
|
|
||||||
C.delete_apatseq(sequence.pointer.pointer,
|
C.delete_apatseq(sequence.pointer.pointer,
|
||||||
&errno, &errmsg)
|
&errno, &errmsg)
|
||||||
|
|
||||||
@ -287,6 +317,6 @@ func (pattern ApatPattern) FindAllIndex(sequence ApatSequence, limits ...int) (l
|
|||||||
return loc
|
return loc
|
||||||
}
|
}
|
||||||
|
|
||||||
func AllocatedApaSequences() int {
|
// func AllocatedApaSequences() int {
|
||||||
return _AllocatedApaSequences
|
// return int(_AllocatedApaSequences)
|
||||||
}
|
// }
|
||||||
|
@ -291,6 +291,9 @@ func _Pcr(seq ApatSequence,
|
|||||||
match.Recycle()
|
match.Recycle()
|
||||||
|
|
||||||
annot["reverse_error"] = errj
|
annot["reverse_error"] = errj
|
||||||
|
|
||||||
|
// log.Debugf("amplicon sequence capacity : %d", cap(amplicon.Sequence()))
|
||||||
|
|
||||||
results = append(results, amplicon)
|
results = append(results, amplicon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,6 +367,7 @@ func _Pcr(seq ApatSequence,
|
|||||||
|
|
||||||
annot["reverse_error"] = erri
|
annot["reverse_error"] = erri
|
||||||
results = append(results, amplicon)
|
results = append(results, amplicon)
|
||||||
|
// log.Debugf("amplicon sequence capacity : %d", cap(amplicon.Sequence()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,6 +401,10 @@ func _PCRSlice(sequences obiseq.BioSequenceSlice,
|
|||||||
|
|
||||||
if len(sequences) > 0 {
|
if len(sequences) > 0 {
|
||||||
seq, _ := MakeApatSequence(sequences[0], options.Circular())
|
seq, _ := MakeApatSequence(sequences[0], options.Circular())
|
||||||
|
|
||||||
|
// if AllocatedApaSequences() == 0 {
|
||||||
|
// log.Panicln("Bizarre....")
|
||||||
|
// }
|
||||||
amplicons := _Pcr(seq, sequences[0], options)
|
amplicons := _Pcr(seq, sequences[0], options)
|
||||||
|
|
||||||
if len(amplicons) > 0 {
|
if len(amplicons) > 0 {
|
||||||
@ -411,6 +419,8 @@ func _PCRSlice(sequences obiseq.BioSequenceSlice,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log.Println(AllocatedApaSequences())
|
||||||
|
|
||||||
// seq.Free()
|
// seq.Free()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user