mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-12-08 08:40:26 +00:00
A global version of a Slice pool
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package obiseq
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
||||
@@ -23,20 +22,53 @@ func __make_default_qualities__(length int) Quality {
|
||||
|
||||
type Annotation map[string]interface{}
|
||||
|
||||
type __sequence__ struct {
|
||||
id bytes.Buffer
|
||||
definition bytes.Buffer
|
||||
sequence bytes.Buffer
|
||||
qualities bytes.Buffer
|
||||
feature bytes.Buffer
|
||||
type _BioSequence struct {
|
||||
id string
|
||||
definition string
|
||||
sequence []byte
|
||||
qualities []byte
|
||||
feature []byte
|
||||
annotations Annotation
|
||||
}
|
||||
|
||||
type BioSequence struct {
|
||||
sequence *__sequence__
|
||||
sequence *_BioSequence
|
||||
}
|
||||
|
||||
type BioSequenceSlice []BioSequence
|
||||
func MakeEmptyBioSequence() BioSequence {
|
||||
bs := _BioSequence{
|
||||
id: "",
|
||||
definition: "",
|
||||
sequence: nil,
|
||||
qualities: nil,
|
||||
feature: nil,
|
||||
annotations: nil,
|
||||
}
|
||||
return BioSequence{&bs}
|
||||
}
|
||||
|
||||
func MakeBioSequence(id string,
|
||||
sequence []byte,
|
||||
definition string) BioSequence {
|
||||
bs := MakeEmptyBioSequence()
|
||||
bs.SetId(id)
|
||||
bs.SetSequence(sequence)
|
||||
bs.SetDefinition(definition)
|
||||
return bs
|
||||
}
|
||||
|
||||
func (sequence *BioSequence) Recycle() {
|
||||
|
||||
pseq := sequence.sequence
|
||||
|
||||
RecycleSlice(pseq.sequence)
|
||||
RecycleSlice(pseq.feature)
|
||||
RecycleSlice(pseq.feature)
|
||||
|
||||
RecycleAnnotation(pseq.annotations)
|
||||
|
||||
sequence.sequence = nil
|
||||
}
|
||||
|
||||
var NilBioSequence = BioSequence{sequence: nil}
|
||||
|
||||
@@ -44,75 +76,66 @@ func (s BioSequence) IsNil() bool {
|
||||
return s.sequence == nil
|
||||
}
|
||||
|
||||
func (s *BioSequence) Reset() {
|
||||
s.sequence.id.Reset()
|
||||
s.sequence.definition.Reset()
|
||||
s.sequence.sequence.Reset()
|
||||
s.sequence.qualities.Reset()
|
||||
s.sequence.feature.Reset()
|
||||
|
||||
for k := range s.sequence.annotations {
|
||||
delete(s.sequence.annotations, k)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s BioSequence) Copy() BioSequence {
|
||||
new_seq := MakeEmptyBioSequence()
|
||||
new_seq.sequence.id.Write(s.sequence.id.Bytes())
|
||||
new_seq.sequence.definition.Write(s.sequence.definition.Bytes())
|
||||
new_seq.sequence.sequence.Write(s.sequence.sequence.Bytes())
|
||||
new_seq.sequence.qualities.Write(s.sequence.qualities.Bytes())
|
||||
new_seq.sequence.feature.Write(s.sequence.feature.Bytes())
|
||||
newSeq := MakeEmptyBioSequence()
|
||||
|
||||
newSeq.sequence.id = s.sequence.id
|
||||
newSeq.sequence.definition = s.sequence.definition
|
||||
|
||||
newSeq.sequence.sequence = GetSlice(s.sequence.sequence...)
|
||||
newSeq.sequence.qualities = GetSlice(s.sequence.qualities...)
|
||||
newSeq.sequence.feature = GetSlice(s.sequence.feature...)
|
||||
|
||||
if len(s.sequence.annotations) > 0 {
|
||||
goutils.CopyMap(new_seq.sequence.annotations,
|
||||
s.sequence.annotations)
|
||||
newSeq.sequence.annotations = GetAnnotation(s.sequence.annotations)
|
||||
}
|
||||
|
||||
return new_seq
|
||||
return newSeq
|
||||
}
|
||||
|
||||
func (s BioSequence) Id() string {
|
||||
return s.sequence.id.String()
|
||||
return s.sequence.id
|
||||
}
|
||||
func (s BioSequence) Definition() string {
|
||||
return s.sequence.definition.String()
|
||||
return s.sequence.definition
|
||||
}
|
||||
|
||||
func (s BioSequence) Sequence() []byte {
|
||||
return s.sequence.sequence.Bytes()
|
||||
return s.sequence.sequence
|
||||
}
|
||||
|
||||
func (s BioSequence) String() string {
|
||||
return s.sequence.sequence.String()
|
||||
return string(s.sequence.sequence)
|
||||
}
|
||||
func (s BioSequence) Length() int {
|
||||
return s.sequence.sequence.Len()
|
||||
return len(s.sequence.sequence)
|
||||
}
|
||||
|
||||
func (s BioSequence) HasQualities() bool {
|
||||
return s.sequence.qualities.Len() > 0
|
||||
return len(s.sequence.qualities) > 0
|
||||
}
|
||||
|
||||
func (s BioSequence) Qualities() Quality {
|
||||
if s.HasQualities() {
|
||||
return s.sequence.qualities.Bytes()
|
||||
return s.sequence.qualities
|
||||
} else {
|
||||
return __make_default_qualities__(s.sequence.sequence.Len())
|
||||
return __make_default_qualities__(len(s.sequence.sequence))
|
||||
}
|
||||
}
|
||||
|
||||
func (s BioSequence) Features() string {
|
||||
return s.sequence.feature.String()
|
||||
return string(s.sequence.feature)
|
||||
}
|
||||
|
||||
func (s BioSequence) Annotations() Annotation {
|
||||
if s.sequence.annotations == nil {
|
||||
s.sequence.annotations = GetAnnotation()
|
||||
}
|
||||
return s.sequence.annotations
|
||||
}
|
||||
|
||||
func (s BioSequence) MD5() [16]byte {
|
||||
return md5.Sum(s.sequence.sequence.Bytes())
|
||||
return md5.Sum(s.sequence.sequence)
|
||||
}
|
||||
|
||||
func (s BioSequence) Count() int {
|
||||
@@ -144,50 +167,55 @@ func (s BioSequence) Taxid() int {
|
||||
}
|
||||
|
||||
func (s BioSequence) SetId(id string) {
|
||||
s.sequence.id.Reset()
|
||||
s.sequence.id.WriteString(id)
|
||||
s.sequence.id = id
|
||||
}
|
||||
|
||||
func (s BioSequence) SetDefinition(definition string) {
|
||||
s.sequence.definition.Reset()
|
||||
s.sequence.definition.WriteString(definition)
|
||||
s.sequence.definition = definition
|
||||
}
|
||||
|
||||
func (s BioSequence) SetFeatures(feature string) {
|
||||
s.sequence.feature.Reset()
|
||||
s.sequence.feature.WriteString(feature)
|
||||
func (s BioSequence) SetFeatures(feature []byte) {
|
||||
if cap(s.sequence.feature) >= 300 {
|
||||
RecycleSlice(s.sequence.feature)
|
||||
}
|
||||
s.sequence.feature = feature
|
||||
}
|
||||
|
||||
func (s BioSequence) SetSequence(sequence []byte) {
|
||||
s.sequence.sequence.Reset()
|
||||
s.sequence.sequence.Write(sequence)
|
||||
if s.sequence.sequence != nil {
|
||||
RecycleSlice(s.sequence.sequence)
|
||||
}
|
||||
s.sequence.sequence = sequence
|
||||
}
|
||||
|
||||
func (s BioSequence) SetQualities(qualities Quality) {
|
||||
s.sequence.qualities.Reset()
|
||||
s.sequence.qualities.Write(qualities)
|
||||
if s.sequence.qualities != nil {
|
||||
RecycleSlice(s.sequence.qualities)
|
||||
}
|
||||
s.sequence.qualities = qualities
|
||||
}
|
||||
|
||||
func (s BioSequence) WriteQualities(data []byte) (int, error) {
|
||||
return s.sequence.qualities.Write(data)
|
||||
s.sequence.qualities = append(s.sequence.qualities, data...)
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func (s BioSequence) WriteByteQualities(data byte) error {
|
||||
return s.sequence.qualities.WriteByte(data)
|
||||
s.sequence.qualities = append(s.sequence.qualities, data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s BioSequence) Write(data []byte) (int, error) {
|
||||
return s.sequence.sequence.Write(data)
|
||||
s.sequence.sequence = append(s.sequence.sequence, data...)
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func (s BioSequence) WriteString(data string) (int, error) {
|
||||
return s.sequence.sequence.WriteString(data)
|
||||
bdata := []byte(data)
|
||||
return s.Write(bdata)
|
||||
}
|
||||
|
||||
func (s BioSequence) WriteByte(data byte) error {
|
||||
return s.sequence.sequence.WriteByte(data)
|
||||
}
|
||||
|
||||
func (s BioSequence) WriteRune(data rune) (int, error) {
|
||||
return s.sequence.sequence.WriteRune(data)
|
||||
s.sequence.sequence = append(s.sequence.sequence, data)
|
||||
return nil
|
||||
}
|
||||
|
||||
4
pkg/obiseq/biosequenceslice.go
Normal file
4
pkg/obiseq/biosequenceslice.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package obiseq
|
||||
|
||||
type BioSequenceSlice []BioSequence
|
||||
|
||||
@@ -2,33 +2,81 @@ package obiseq
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
||||
)
|
||||
|
||||
var __bioseq__pool__ = sync.Pool{
|
||||
var _BioSequenceByteSlicePool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
var bs __sequence__
|
||||
bs.annotations = make(Annotation, 50)
|
||||
bs := make([]byte, 0, 300)
|
||||
return &bs
|
||||
},
|
||||
}
|
||||
|
||||
func MakeEmptyBioSequence() BioSequence {
|
||||
bs := BioSequence{__bioseq__pool__.Get().(*__sequence__)}
|
||||
return bs
|
||||
func RecycleSlice(s []byte) {
|
||||
s0 := s[:0]
|
||||
_BioSequenceByteSlicePool.Put(&s0)
|
||||
}
|
||||
|
||||
func MakeBioSequence(id string,
|
||||
sequence []byte,
|
||||
definition string) BioSequence {
|
||||
bs := MakeEmptyBioSequence()
|
||||
bs.SetId(id)
|
||||
bs.Write(sequence)
|
||||
bs.SetDefinition(definition)
|
||||
return bs
|
||||
func GetSlice(values ...byte) []byte {
|
||||
s := *(_BioSequenceByteSlicePool.Get().(*[]byte))
|
||||
|
||||
if len(values) > 0 {
|
||||
s = append(s, values...)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (sequence *BioSequence) Recycle() {
|
||||
sequence.Reset()
|
||||
__bioseq__pool__.Put(sequence.sequence)
|
||||
sequence.sequence = nil
|
||||
var BioSequenceAnnotationPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
bs := make(Annotation, 100)
|
||||
return &bs
|
||||
},
|
||||
}
|
||||
|
||||
func RecycleAnnotation(a Annotation) {
|
||||
for k := range a {
|
||||
delete(a, k)
|
||||
}
|
||||
BioSequenceAnnotationPool.Put(&(a))
|
||||
}
|
||||
|
||||
func GetAnnotation(values ...Annotation) Annotation {
|
||||
a := *(BioSequenceAnnotationPool.Get().(*Annotation))
|
||||
|
||||
if len(values) > 0 {
|
||||
goutils.CopyMap(a, values[0])
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// var __bioseq__pool__ = sync.Pool{
|
||||
// New: func() interface{} {
|
||||
// var bs _BioSequence
|
||||
// bs.annotations = make(Annotation, 50)
|
||||
// return &bs
|
||||
// },
|
||||
// }
|
||||
|
||||
// func MakeEmptyBioSequence() BioSequence {
|
||||
// bs := BioSequence{__bioseq__pool__.Get().(*_BioSequence)}
|
||||
// return bs
|
||||
// }
|
||||
|
||||
// func MakeBioSequence(id string,
|
||||
// sequence []byte,
|
||||
// definition string) BioSequence {
|
||||
// bs := MakeEmptyBioSequence()
|
||||
// bs.SetId(id)
|
||||
// bs.Write(sequence)
|
||||
// bs.SetDefinition(definition)
|
||||
// return bs
|
||||
// }
|
||||
|
||||
// func (sequence *BioSequence) Recycle() {
|
||||
// sequence.Reset()
|
||||
// __bioseq__pool__.Put(sequence.sequence)
|
||||
// sequence.sequence = nil
|
||||
// }
|
||||
|
||||
@@ -11,7 +11,7 @@ func (sequence BioSequence) ReverseComplement(inplace bool) BioSequence {
|
||||
sequence = sequence.Copy()
|
||||
}
|
||||
|
||||
s := sequence.sequence.sequence.Bytes()
|
||||
s := sequence.sequence.sequence
|
||||
|
||||
for i, j := sequence.Length()-1, 0; i >= j; i-- {
|
||||
|
||||
@@ -20,7 +20,5 @@ func (sequence BioSequence) ReverseComplement(inplace bool) BioSequence {
|
||||
j++
|
||||
}
|
||||
|
||||
sequence.sequence.id.WriteString("_revcomp")
|
||||
|
||||
return sequence
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ package obiseq
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
||||
)
|
||||
|
||||
// Returns a sub sequence start from position 'from' included,
|
||||
@@ -23,21 +21,22 @@ func (sequence BioSequence) Subsequence(from, to int, circular bool) (BioSequenc
|
||||
return NilBioSequence, errors.New("to out of bounds")
|
||||
}
|
||||
|
||||
var new_seq BioSequence
|
||||
var newSeq BioSequence
|
||||
|
||||
if from < to {
|
||||
new_seq = MakeEmptyBioSequence()
|
||||
new_seq.Write(sequence.Sequence()[from:to])
|
||||
fmt.Fprintf(&new_seq.sequence.id, "%s_sub[%d..%d]", sequence.Id(), from+1, to)
|
||||
new_seq.sequence.definition.Write(sequence.sequence.definition.Bytes())
|
||||
newSeq = MakeEmptyBioSequence()
|
||||
newSeq.Write(sequence.Sequence()[from:to])
|
||||
|
||||
newSeq.sequence.id = fmt.Sprintf("%s_sub[%d..%d]", sequence.Id(), from+1, to)
|
||||
newSeq.sequence.definition = sequence.sequence.definition
|
||||
} else {
|
||||
new_seq, _ = sequence.Subsequence(from, sequence.Length(), false)
|
||||
new_seq.Write(sequence.Sequence()[0:to])
|
||||
newSeq, _ = sequence.Subsequence(from, sequence.Length(), false)
|
||||
newSeq.Write(sequence.Sequence()[0:to])
|
||||
}
|
||||
|
||||
if len(sequence.Annotations()) > 0 {
|
||||
goutils.CopyMap(new_seq.Annotations(), sequence.Annotations())
|
||||
newSeq.sequence.annotations = GetAnnotation(sequence.Annotations())
|
||||
}
|
||||
|
||||
return new_seq, nil
|
||||
return newSeq, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user