remove the slice pool management

This commit is contained in:
Eric Coissac
2024-09-24 16:31:30 +02:00
parent 2b4a633c30
commit 241f2286f2
17 changed files with 23 additions and 84 deletions

View File

@ -529,7 +529,6 @@ func PCRSliceWorker(options ...WithOption) obiseq.SeqSliceWorker {
opt := MakeOptions(options) opt := MakeOptions(options)
worker := func(sequences obiseq.BioSequenceSlice) (obiseq.BioSequenceSlice, error) { worker := func(sequences obiseq.BioSequenceSlice) (obiseq.BioSequenceSlice, error) {
result := _PCRSlice(sequences, opt) result := _PCRSlice(sequences, opt)
sequences.Recycle(true)
return result, nil return result, nil
} }

View File

@ -49,7 +49,6 @@ func ISequenceChunk(iterator obiiter.IBioSequence,
b := data.Get() b := data.Get()
source = b.Source() source = b.Source()
*chunk = append(*chunk, b.Slice()...) *chunk = append(*chunk, b.Slice()...)
b.Recycle(false)
} }
lock.Lock() lock.Lock()

View File

@ -107,8 +107,6 @@ func ISequenceSubChunk(iterator obiiter.IBioSequence,
batch.Slice()[i] = nil batch.Slice()[i] = nil
} }
batch.Recycle(false)
_By(func(p1, p2 *sSS) bool { _By(func(p1, p2 *sSS) bool {
return p1.code < p2.code return p1.code < p2.code
}).Sort(ordered) }).Sort(ordered)

View File

@ -95,10 +95,7 @@ func IUniqueSequence(iterator obiiter.IBioSequence,
if icat < 0 || len(batch.Slice()) == 1 { if icat < 0 || len(batch.Slice()) == 1 {
// No more sub classification of sequence or only a single sequence // No more sub classification of sequence or only a single sequence
if opts.NoSingleton() && len(batch.Slice()) == 1 && batch.Slice()[0].Count() == 1 { if !(opts.NoSingleton() && len(batch.Slice()) == 1 && batch.Slice()[0].Count() == 1) {
// We remove singleton from output
batch.Recycle(true)
} else {
iUnique.Push(batch.Reorder(nextOrder())) iUnique.Push(batch.Reorder(nextOrder()))
} }
} else { } else {

View File

@ -108,14 +108,3 @@ func (batch BioSequenceBatch) Pop0() *obiseq.BioSequence {
func (batch BioSequenceBatch) IsNil() bool { func (batch BioSequenceBatch) IsNil() bool {
return batch.slice == nil return batch.slice == nil
} }
// Recycle cleans up the BioSequenceBatch by recycling its elements and resetting its slice.
//
// If including_seq is true, each element of the BioSequenceBatch's slice is recycled using the Recycle method,
// and then set to nil. If including_seq is false, each element is simply set to nil.
//
// This function does not return anything.
func (batch BioSequenceBatch) Recycle(including_seq bool) {
batch.slice.Recycle(including_seq)
batch.slice = nil
}

View File

@ -459,7 +459,6 @@ func (iterator IBioSequence) Rebatch(size int) IBioSequence {
} }
i += to_push i += to_push
} }
seqs.Recycle(false)
} }
log.Debug("End of the rebatch loop") log.Debug("End of the rebatch loop")
if len(buffer) > 0 { if len(buffer) > 0 {
@ -521,7 +520,6 @@ func (iterator IBioSequence) Recycle() {
o := batch.Order() o := batch.Order()
log.Debugln("Recycling batch #", o) log.Debugln("Recycling batch #", o)
recycled += batch.Len() recycled += batch.Len()
batch.Recycle(true)
log.Debugln("Batch #", o, " recycled") log.Debugln("Batch #", o, " recycled")
} }
log.Debugf("End of the recycling of %d Bioseq objects", recycled) log.Debugf("End of the recycling of %d Bioseq objects", recycled)
@ -529,8 +527,7 @@ func (iterator IBioSequence) Recycle() {
func (iterator IBioSequence) Consume() { func (iterator IBioSequence) Consume() {
for iterator.Next() { for iterator.Next() {
batch := iterator.Get() iterator.Get()
batch.Recycle(false)
} }
} }
@ -548,7 +545,6 @@ func (iterator IBioSequence) Count(recycle bool) (int, int, int) {
reads += seq.Count() reads += seq.Count()
nucleotides += seq.Len() nucleotides += seq.Len()
} }
batch.Recycle(recycle)
} }
log.Debugf("End of the counting of %d Bioseq objects", variants) log.Debugf("End of the counting of %d Bioseq objects", variants)
return variants, reads, nucleotides return variants, reads, nucleotides
@ -602,7 +598,6 @@ func (iterator IBioSequence) DivideOn(predicate obiseq.SequencePredicate,
falseSlice = obiseq.MakeBioSequenceSlice() falseSlice = obiseq.MakeBioSequenceSlice()
} }
} }
seqs.Recycle(false)
} }
if len(trueSlice) > 0 { if len(trueSlice) > 0 {
@ -749,7 +744,6 @@ func (iterator IBioSequence) Load() (string, obiseq.BioSequenceSlice) {
} }
log.Debugf("append %d sequences", b.Len()) log.Debugf("append %d sequences", b.Len())
chunk = append(chunk, b.Slice()...) chunk = append(chunk, b.Slice()...)
b.Recycle(false)
} }
return source, chunk return source, chunk

View File

@ -93,7 +93,6 @@ func (iterator IBioSequence) Distribute(class *obiseq.BioSequenceClassifier, siz
slices[key] = &s slices[key] = &s
} }
} }
seqs.Recycle(false)
} }
for key, slice := range slices { for key, slice := range slices {

View File

@ -55,7 +55,6 @@ func IFragments(minsize, length, overlap, size, nworkers int) Pipeable {
} }
} // End of the slice loop } // End of the slice loop
newiter.Push(MakeBioSequenceBatch(source, sl.Order(), news)) newiter.Push(MakeBioSequenceBatch(source, sl.Order(), news))
sl.Recycle(false)
} // End of the iterator loop } // End of the iterator loop
// if len(news) > 0 { // if len(news) > 0 {

View File

@ -228,7 +228,6 @@ func LuaProcessor(iterator obiiter.IBioSequence, name, program string, breakOnEr
} }
newIter.Push(obiiter.MakeBioSequenceBatch(seqs.Source(), seqs.Order(), ns)) newIter.Push(obiiter.MakeBioSequenceBatch(seqs.Source(), seqs.Order(), ns))
seqs.Recycle(false)
} }
newIter.Done() newIter.Done()

View File

@ -7,7 +7,7 @@ import (
// TODO: The version number is extracted from git. This induces that the version // TODO: The version number is extracted from git. This induces that the version
// corresponds to the last commit, and not the one when the file will be // corresponds to the last commit, and not the one when the file will be
// commited // commited
var _Commit = "05bf2bf" var _Commit = "2b4a633"
var _Version = "Release 4.2.0" var _Version = "Release 4.2.0"
// Version returns the version of the obitools package. // Version returns the version of the obitools package.

View File

@ -64,6 +64,7 @@ type BioSequence struct {
qualities []byte // The quality scores of the sequence. qualities []byte // The quality scores of the sequence.
feature []byte feature []byte
paired *BioSequence // A pointer to the paired sequence paired *BioSequence // A pointer to the paired sequence
revcomp *BioSequence // A pointer to the reverse complemented sequence
annotations Annotation annotations Annotation
annot_lock *sync.Mutex annot_lock *sync.Mutex
} }
@ -78,7 +79,8 @@ func NewEmptyBioSequence(preallocate int) *BioSequence {
seq := []byte(nil) seq := []byte(nil)
if preallocate > 0 { if preallocate > 0 {
seq = GetSlice(preallocate) // seq = GetSlice(preallocate)
seq = make([]byte, 0, preallocate)
} }
return &BioSequence{ return &BioSequence{
@ -89,6 +91,7 @@ func NewEmptyBioSequence(preallocate int) *BioSequence {
qualities: nil, qualities: nil,
feature: nil, feature: nil,
paired: nil, paired: nil,
revcomp: nil,
annotations: nil, annotations: nil,
annot_lock: &sync.Mutex{}, annot_lock: &sync.Mutex{},
} }
@ -426,9 +429,6 @@ func (s *BioSequence) SetFeatures(feature []byte) {
// Parameters: // Parameters:
// - sequence: a byte slice representing the sequence to be set. // - sequence: a byte slice representing the sequence to be set.
func (s *BioSequence) SetSequence(sequence []byte) { func (s *BioSequence) SetSequence(sequence []byte) {
if s.sequence != nil {
RecycleSlice(&s.sequence)
}
s.sequence = obiutils.InPlaceToLower(CopySlice(sequence)) s.sequence = obiutils.InPlaceToLower(CopySlice(sequence))
} }

View File

@ -1,8 +1,6 @@
package obiseq package obiseq
import ( import (
"sync"
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiutils" "git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiutils"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
@ -14,13 +12,6 @@ import (
// a memory pool of BioSequenceSlice is managed to limit allocations. // a memory pool of BioSequenceSlice is managed to limit allocations.
type BioSequenceSlice []*BioSequence type BioSequenceSlice []*BioSequence
var _BioSequenceSlicePool = sync.Pool{
New: func() interface{} {
bs := make(BioSequenceSlice, 0, 10)
return &bs
},
}
// NewBioSequenceSlice returns a new BioSequenceSlice with the specified size. // NewBioSequenceSlice returns a new BioSequenceSlice with the specified size.
// //
// The size parameter is optional. If provided, the returned slice will be // The size parameter is optional. If provided, the returned slice will be
@ -28,13 +19,14 @@ var _BioSequenceSlicePool = sync.Pool{
// //
// Returns a pointer to the newly created BioSequenceSlice. // Returns a pointer to the newly created BioSequenceSlice.
func NewBioSequenceSlice(size ...int) *BioSequenceSlice { func NewBioSequenceSlice(size ...int) *BioSequenceSlice {
slice := _BioSequenceSlicePool.Get().(*BioSequenceSlice) capacity := 0
if len(size) > 0 { if len(size) > 0 {
s := size[0] capacity = size[0]
slice = slice.EnsureCapacity(s)
(*slice) = (*slice)[0:s]
} }
return slice
slice := make(BioSequenceSlice, capacity)
return &slice
} }
// MakeBioSequenceSlice creates a new BioSequenceSlice with the specified size(s). // MakeBioSequenceSlice creates a new BioSequenceSlice with the specified size(s).
@ -48,34 +40,6 @@ func MakeBioSequenceSlice(size ...int) BioSequenceSlice {
return *NewBioSequenceSlice(size...) return *NewBioSequenceSlice(size...)
} }
// Recycle cleans up the BioSequenceSlice by recycling its elements and resetting its length.
//
// If including_seq is true, each element of the BioSequenceSlice is recycled using the Recycle method,
// and then set to nil. If including_seq is false, each element is simply set to nil.
//
// The function does not return anything.
func (s *BioSequenceSlice) Recycle(including_seq bool) {
if s == nil {
log.Panicln("Trying too recycle a nil pointer")
}
// Code added to potentially limit memory leaks
if including_seq {
for i := range *s {
(*s)[i].Recycle()
(*s)[i] = nil
}
} else {
for i := range *s {
(*s)[i] = nil
}
}
*s = (*s)[:0]
_BioSequenceSlicePool.Put(s)
}
// EnsureCapacity ensures that the BioSequenceSlice has a minimum capacity // EnsureCapacity ensures that the BioSequenceSlice has a minimum capacity
// //
// It takes an integer `capacity` as a parameter, which represents the desired minimum capacity of the BioSequenceSlice. // It takes an integer `capacity` as a parameter, which represents the desired minimum capacity of the BioSequenceSlice.

View File

@ -295,6 +295,5 @@ func (sequences BioSequenceSlice) Merge(na string, statsOn StatsOnDescriptions)
} }
} }
sequences.Recycle(false)
return seq return seq
} }

View File

@ -43,12 +43,21 @@ func nucComplement(n byte) byte {
// The function returns the reverse complemented BioSequence. // The function returns the reverse complemented BioSequence.
func (sequence *BioSequence) ReverseComplement(inplace bool) *BioSequence { func (sequence *BioSequence) ReverseComplement(inplace bool) *BioSequence {
original := (*BioSequence)(nil)
if sequence == nil { if sequence == nil {
return nil return nil
} }
if sequence.revcomp != nil {
return sequence.revcomp
}
if !inplace { if !inplace {
sequence = sequence.Copy() original = sequence
sequence.revcomp = sequence.Copy()
sequence = sequence.revcomp
sequence.revcomp = original
} }
s := sequence.sequence s := sequence.sequence

View File

@ -317,8 +317,6 @@ func MinionDenoise(graph *obigraph.Graph[*obiseq.BioSequence, Mutation],
} }
pack.Recycle(false)
} else { } else {
clean = obiseq.NewBioSequence(v.Id(), v.Sequence(), v.Definition()) clean = obiseq.NewBioSequence(v.Id(), v.Sequence(), v.Definition())
clean.SetAttribute("obiconsensus_consensus", false) clean.SetAttribute("obiconsensus_consensus", false)
@ -403,7 +401,6 @@ func MinionClusterDenoise(graph *obigraph.Graph[*obiseq.BioSequence, Mutation],
clean = (*graph.Vertices)[i].Copy() clean = (*graph.Vertices)[i].Copy()
clean.SetAttribute("obiconsensus_consensus", false) clean.SetAttribute("obiconsensus_consensus", false)
} }
pack.Recycle(false)
clean.SetAttribute(sample_key, graph.Name) clean.SetAttribute(sample_key, graph.Name)
@ -436,7 +433,6 @@ func CLIOBIMinion(itertator obiiter.IBioSequence) obiiter.IBioSequence {
log.Infof("Sequence dataset of %d sequeences loaded\n", len(db)) log.Infof("Sequence dataset of %d sequeences loaded\n", len(db))
samples := SeqBySamples(db, CLISampleAttribute()) samples := SeqBySamples(db, CLISampleAttribute())
db.Recycle(false)
log.Infof("Dataset composed of %d samples\n", len(samples)) log.Infof("Dataset composed of %d samples\n", len(samples))

View File

@ -107,7 +107,6 @@ func IMatrix(iterator obiiter.IBioSequence) *MatrixData {
for _, seq := range batch.Slice() { for _, seq := range batch.Slice() {
summary.Update(seq, mapAttribute) summary.Update(seq, mapAttribute)
} }
batch.Recycle(true)
} }
waiter.Done() waiter.Done()
} }

View File

@ -172,7 +172,6 @@ func ISummary(iterator obiiter.IBioSequence, summarise []string) map[string]inte
for _, seq := range batch.Slice() { for _, seq := range batch.Slice() {
summary.Update(seq) summary.Update(seq)
} }
batch.Recycle(true)
} }
waiter.Done() waiter.Done()
} }