mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
Patch memory error related to []byte pool
This commit is contained in:
@ -1,26 +0,0 @@
|
||||
package cutils
|
||||
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ByteSlice builds a byte Slice over a C pointer returned by a
|
||||
// C function.
|
||||
// The C pointer has to be passed as an unsafe.Pointer
|
||||
// and the size of the pointed memery area has to be
|
||||
// indicated through the size parameter.
|
||||
// No memory allocation is done by that function. It
|
||||
// just consists in mapping a Go object too a C one.
|
||||
func ByteSlice(pointer unsafe.Pointer, size int) []byte {
|
||||
var s []byte
|
||||
|
||||
h := (*reflect.SliceHeader)((unsafe.Pointer(&s)))
|
||||
h.Cap = size
|
||||
h.Len = size
|
||||
h.Data = uintptr(pointer)
|
||||
|
||||
return s
|
||||
}
|
@ -71,10 +71,10 @@ func _BuildAlignment(seqA, seqB []byte, path []int, gap byte, bufferA, bufferB *
|
||||
func BuildAlignment(seqA, seqB *obiseq.BioSequence,
|
||||
path []int, gap byte) (*obiseq.BioSequence, *obiseq.BioSequence) {
|
||||
|
||||
bufferSA := obiseq.GetSlice()
|
||||
bufferSA := obiseq.GetSlice(seqA.Length())
|
||||
defer obiseq.RecycleSlice(&bufferSA)
|
||||
|
||||
bufferSB := obiseq.GetSlice()
|
||||
bufferSB := obiseq.GetSlice(seqB.Length())
|
||||
defer obiseq.RecycleSlice(&bufferSB)
|
||||
|
||||
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, gap,
|
||||
@ -115,12 +115,12 @@ func BuildAlignment(seqA, seqB *obiseq.BioSequence,
|
||||
// return.
|
||||
func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int) (*obiseq.BioSequence, int) {
|
||||
|
||||
bufferSA := obiseq.GetSlice()
|
||||
bufferSB := obiseq.GetSlice()
|
||||
bufferSA := obiseq.GetSlice(seqA.Length())
|
||||
bufferSB := obiseq.GetSlice(seqB.Length())
|
||||
defer obiseq.RecycleSlice(&bufferSB)
|
||||
|
||||
bufferQA := obiseq.GetSlice()
|
||||
bufferQB := obiseq.GetSlice()
|
||||
bufferQA := obiseq.GetSlice(seqA.Length())
|
||||
bufferQB := obiseq.GetSlice(seqB.Length())
|
||||
defer obiseq.RecycleSlice(&bufferQB)
|
||||
|
||||
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, ' ',
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/cutils"
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiiter"
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
||||
)
|
||||
@ -31,13 +30,7 @@ func _FastseqReader(seqfile C.fast_kseq_p,
|
||||
|
||||
s := seqfile.seq
|
||||
|
||||
csequence := cutils.ByteSlice(unsafe.Pointer(s.seq.s), int(s.seq.l))
|
||||
sequence := obiseq.GetSlice()
|
||||
sequence = append(sequence, csequence...)
|
||||
|
||||
//sequence := C.GoBytes(unsafe.Pointer(s.seq.s),
|
||||
// C.int(s.seq.l))
|
||||
|
||||
sequence := C.GoBytes(unsafe.Pointer(s.seq.s), C.int(s.seq.l))
|
||||
name := C.GoString(s.name.s)
|
||||
|
||||
if s.comment.l > C.ulong(0) {
|
||||
@ -49,12 +42,23 @@ func _FastseqReader(seqfile C.fast_kseq_p,
|
||||
rep := obiseq.NewBioSequence(name, sequence, comment)
|
||||
|
||||
if s.qual.l > C.ulong(0) {
|
||||
cquality := cutils.ByteSlice(unsafe.Pointer(s.qual.s), int(s.qual.l))
|
||||
cquality := unsafe.Slice(s.qual.s, C.int(s.qual.l))
|
||||
l := int(s.qual.l)
|
||||
quality := obiseq.GetSlice()
|
||||
quality := obiseq.GetSlice(l)
|
||||
shift := uint8(seqfile.shift)
|
||||
|
||||
for j := 0; j < l; j++ {
|
||||
func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Println("cquality:", cquality,
|
||||
"s.qual.s:", s.qual.s,
|
||||
"quality:", quality)
|
||||
log.Panic("panic occurred:", err)
|
||||
}
|
||||
}()
|
||||
quality = append(quality, uint8(cquality[j])-shift)
|
||||
}()
|
||||
}
|
||||
|
||||
rep.SetQualities(quality)
|
||||
|
@ -129,9 +129,9 @@ func (s *BioSequence) Copy() *BioSequence {
|
||||
newSeq.id = s.id
|
||||
newSeq.definition = s.definition
|
||||
|
||||
newSeq.sequence = GetSlice(s.sequence...)
|
||||
newSeq.qualities = GetSlice(s.qualities...)
|
||||
newSeq.feature = GetSlice(s.feature...)
|
||||
newSeq.sequence = CopySlice(s.sequence)
|
||||
newSeq.qualities = CopySlice(s.qualities)
|
||||
newSeq.feature = CopySlice(s.feature)
|
||||
|
||||
if len(s.annotations) > 0 {
|
||||
newSeq.annotations = GetAnnotation(s.annotations)
|
||||
@ -340,7 +340,6 @@ func (s *BioSequence) ClearQualities() {
|
||||
s.qualities = s.qualities[0:0]
|
||||
}
|
||||
|
||||
|
||||
// A method that appends a byte slice to the sequence.
|
||||
func (s *BioSequence) Write(data []byte) (int, error) {
|
||||
s.sequence = append(s.sequence, data...)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package obiseq
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
||||
@ -14,22 +15,36 @@ var _BioSequenceByteSlicePool = sync.Pool{
|
||||
}
|
||||
|
||||
func RecycleSlice(s *[]byte) {
|
||||
if s != nil && *s != nil {
|
||||
if s != nil && cap(*s) > 0 {
|
||||
*s = (*s)[:0]
|
||||
if cap(*s) == 0 {
|
||||
log.Panicln("trying to store a NIL slice in the pool", s == nil, *s == nil, cap(*s))
|
||||
}
|
||||
_BioSequenceByteSlicePool.Put(s)
|
||||
}
|
||||
}
|
||||
|
||||
func GetSlice(values ...byte) []byte {
|
||||
s := *(_BioSequenceByteSlicePool.Get().(*[]byte))
|
||||
// It returns a slice of bytes from a pool of slices.
|
||||
//
|
||||
// the slice can be prefilled with the provided values
|
||||
func GetSlice(capacity int) []byte {
|
||||
p := _BioSequenceByteSlicePool.Get().(*[]byte)
|
||||
|
||||
if len(values) > 0 {
|
||||
s = append(s, values...)
|
||||
if p == nil || *p == nil || cap(*p) < capacity {
|
||||
s := make([]byte, 0, capacity)
|
||||
p = &s
|
||||
}
|
||||
s := *p
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func CopySlice(src []byte) []byte {
|
||||
sl := GetSlice(len(src))
|
||||
copy(sl,src)
|
||||
return sl
|
||||
}
|
||||
|
||||
var BioSequenceAnnotationPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
bs := make(Annotation, 5)
|
||||
|
Reference in New Issue
Block a user