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,
|
func BuildAlignment(seqA, seqB *obiseq.BioSequence,
|
||||||
path []int, gap byte) (*obiseq.BioSequence, *obiseq.BioSequence) {
|
path []int, gap byte) (*obiseq.BioSequence, *obiseq.BioSequence) {
|
||||||
|
|
||||||
bufferSA := obiseq.GetSlice()
|
bufferSA := obiseq.GetSlice(seqA.Length())
|
||||||
defer obiseq.RecycleSlice(&bufferSA)
|
defer obiseq.RecycleSlice(&bufferSA)
|
||||||
|
|
||||||
bufferSB := obiseq.GetSlice()
|
bufferSB := obiseq.GetSlice(seqB.Length())
|
||||||
defer obiseq.RecycleSlice(&bufferSB)
|
defer obiseq.RecycleSlice(&bufferSB)
|
||||||
|
|
||||||
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, gap,
|
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, gap,
|
||||||
@ -115,12 +115,12 @@ func BuildAlignment(seqA, seqB *obiseq.BioSequence,
|
|||||||
// return.
|
// return.
|
||||||
func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int) (*obiseq.BioSequence, int) {
|
func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int) (*obiseq.BioSequence, int) {
|
||||||
|
|
||||||
bufferSA := obiseq.GetSlice()
|
bufferSA := obiseq.GetSlice(seqA.Length())
|
||||||
bufferSB := obiseq.GetSlice()
|
bufferSB := obiseq.GetSlice(seqB.Length())
|
||||||
defer obiseq.RecycleSlice(&bufferSB)
|
defer obiseq.RecycleSlice(&bufferSB)
|
||||||
|
|
||||||
bufferQA := obiseq.GetSlice()
|
bufferQA := obiseq.GetSlice(seqA.Length())
|
||||||
bufferQB := obiseq.GetSlice()
|
bufferQB := obiseq.GetSlice(seqB.Length())
|
||||||
defer obiseq.RecycleSlice(&bufferQB)
|
defer obiseq.RecycleSlice(&bufferQB)
|
||||||
|
|
||||||
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, ' ',
|
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, ' ',
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
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/obiiter"
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
||||||
)
|
)
|
||||||
@ -31,13 +30,7 @@ func _FastseqReader(seqfile C.fast_kseq_p,
|
|||||||
|
|
||||||
s := seqfile.seq
|
s := seqfile.seq
|
||||||
|
|
||||||
csequence := cutils.ByteSlice(unsafe.Pointer(s.seq.s), int(s.seq.l))
|
sequence := C.GoBytes(unsafe.Pointer(s.seq.s), C.int(s.seq.l))
|
||||||
sequence := obiseq.GetSlice()
|
|
||||||
sequence = append(sequence, csequence...)
|
|
||||||
|
|
||||||
//sequence := C.GoBytes(unsafe.Pointer(s.seq.s),
|
|
||||||
// C.int(s.seq.l))
|
|
||||||
|
|
||||||
name := C.GoString(s.name.s)
|
name := C.GoString(s.name.s)
|
||||||
|
|
||||||
if s.comment.l > C.ulong(0) {
|
if s.comment.l > C.ulong(0) {
|
||||||
@ -49,12 +42,23 @@ func _FastseqReader(seqfile C.fast_kseq_p,
|
|||||||
rep := obiseq.NewBioSequence(name, sequence, comment)
|
rep := obiseq.NewBioSequence(name, sequence, comment)
|
||||||
|
|
||||||
if s.qual.l > C.ulong(0) {
|
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)
|
l := int(s.qual.l)
|
||||||
quality := obiseq.GetSlice()
|
quality := obiseq.GetSlice(l)
|
||||||
shift := uint8(seqfile.shift)
|
shift := uint8(seqfile.shift)
|
||||||
|
|
||||||
for j := 0; j < l; j++ {
|
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)
|
quality = append(quality, uint8(cquality[j])-shift)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
rep.SetQualities(quality)
|
rep.SetQualities(quality)
|
||||||
|
@ -129,9 +129,9 @@ func (s *BioSequence) Copy() *BioSequence {
|
|||||||
newSeq.id = s.id
|
newSeq.id = s.id
|
||||||
newSeq.definition = s.definition
|
newSeq.definition = s.definition
|
||||||
|
|
||||||
newSeq.sequence = GetSlice(s.sequence...)
|
newSeq.sequence = CopySlice(s.sequence)
|
||||||
newSeq.qualities = GetSlice(s.qualities...)
|
newSeq.qualities = CopySlice(s.qualities)
|
||||||
newSeq.feature = GetSlice(s.feature...)
|
newSeq.feature = CopySlice(s.feature)
|
||||||
|
|
||||||
if len(s.annotations) > 0 {
|
if len(s.annotations) > 0 {
|
||||||
newSeq.annotations = GetAnnotation(s.annotations)
|
newSeq.annotations = GetAnnotation(s.annotations)
|
||||||
@ -340,7 +340,6 @@ func (s *BioSequence) ClearQualities() {
|
|||||||
s.qualities = s.qualities[0:0]
|
s.qualities = s.qualities[0:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// A method that appends a byte slice to the sequence.
|
// A method that appends a byte slice to the sequence.
|
||||||
func (s *BioSequence) Write(data []byte) (int, error) {
|
func (s *BioSequence) Write(data []byte) (int, error) {
|
||||||
s.sequence = append(s.sequence, data...)
|
s.sequence = append(s.sequence, data...)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package obiseq
|
package obiseq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
||||||
@ -14,22 +15,36 @@ var _BioSequenceByteSlicePool = sync.Pool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RecycleSlice(s *[]byte) {
|
func RecycleSlice(s *[]byte) {
|
||||||
if s != nil && *s != nil {
|
if s != nil && cap(*s) > 0 {
|
||||||
*s = (*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)
|
_BioSequenceByteSlicePool.Put(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSlice(values ...byte) []byte {
|
// It returns a slice of bytes from a pool of slices.
|
||||||
s := *(_BioSequenceByteSlicePool.Get().(*[]byte))
|
//
|
||||||
|
// the slice can be prefilled with the provided values
|
||||||
|
func GetSlice(capacity int) []byte {
|
||||||
|
p := _BioSequenceByteSlicePool.Get().(*[]byte)
|
||||||
|
|
||||||
if len(values) > 0 {
|
if p == nil || *p == nil || cap(*p) < capacity {
|
||||||
s = append(s, values...)
|
s := make([]byte, 0, capacity)
|
||||||
|
p = &s
|
||||||
}
|
}
|
||||||
|
s := *p
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CopySlice(src []byte) []byte {
|
||||||
|
sl := GetSlice(len(src))
|
||||||
|
copy(sl,src)
|
||||||
|
return sl
|
||||||
|
}
|
||||||
|
|
||||||
var BioSequenceAnnotationPool = sync.Pool{
|
var BioSequenceAnnotationPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
bs := make(Annotation, 5)
|
bs := make(Annotation, 5)
|
||||||
|
Reference in New Issue
Block a user