github.com/Schaudge/hts@v0.0.0-20240223063651-737b4d69d68c/sam/grail.go (about)

     1  //go:generate  ../../base/gtl/generate_randomized_freepool.py --output=record_pool --prefix=Record -DELEM=*Record --package=sam
     2  
     3  package sam
     4  
     5  // This file contains Grail-specific extensions.
     6  
     7  import (
     8  	"bytes"
     9  
    10  	gunsafe "github.com/Schaudge/grailbase/unsafe"
    11  )
    12  
    13  var recordPool    = NewRecordFreePool(func() *Record { return &Record{} }, 1<<20)
    14  
    15  // ResizeScratch makes *buf exactly n bytes long.
    16  func ResizeScratch(buf *[]byte, n int) {
    17  	if cap(*buf) < n {
    18  		// Allocate slightly more memory than needed to prevent frequent
    19  		// reallocation.
    20  		size := (n/16 + 1) * 16
    21  		*buf = make([]byte, n, size)
    22  	} else {
    23  		gunsafe.ExtendBytes(buf, n)
    24  	}
    25  }
    26  
    27  // GetFromFreePool allocates a new empty Record object.
    28  func GetFromFreePool() *Record {
    29  	rec := recordPool.Get()
    30  	rec.Name = ""
    31  	rec.Ref = nil
    32  	rec.MateRef = nil
    33  	rec.Cigar = nil
    34  	rec.Seq = Seq{}
    35  	rec.Qual = nil
    36  	rec.AuxFields = nil
    37  	return rec
    38  }
    39  
    40  // PutInFreePool adds the record to the singleton freepool.  The caller must
    41  // guarantee that there is no outstanding references to the record. It will be
    42  // overwritten in a future.
    43  func PutInFreePool(r *Record) {
    44  	recordPool.Put(r)
    45  }
    46  
    47  // Equal checks if the two records are identical, except for the Scratch field.
    48  func (r *Record) Equal(other *Record) bool {
    49  	return r.Name == other.Name &&
    50  		r.Ref == other.Ref &&
    51  		r.Pos == other.Pos &&
    52  		r.MapQ == other.MapQ &&
    53  		r.Cigar.Equal(other.Cigar) &&
    54  		r.Flags == other.Flags &&
    55  		r.MateRef == other.MateRef &&
    56  		r.MatePos == other.MatePos &&
    57  		r.TempLen == other.TempLen &&
    58  		r.Seq.Equal(other.Seq) &&
    59  		bytes.Equal(r.Qual, other.Qual) &&
    60  		r.AuxFields.Equal(other.AuxFields)
    61  }
    62  
    63  // Equal checks if the two values are identical.
    64  func (s Seq) Equal(other Seq) bool {
    65  	// TODO(satio) Use UnsafeDoubletsToBytes
    66  	if s.Length != other.Length {
    67  		return false
    68  	}
    69  	for i := range s.Seq {
    70  		if s.Seq[i] != other.Seq[i] {
    71  			return false
    72  		}
    73  	}
    74  	return true
    75  }
    76  
    77  // Equal checks if the two values are identical.
    78  func (s Cigar) Equal(other Cigar) bool {
    79  	if len(s) != len(other) {
    80  		return false
    81  	}
    82  	for i := range s {
    83  		if s[i] != other[i] {
    84  			return false
    85  		}
    86  	}
    87  	return true
    88  }
    89  
    90  // Equal checks if the two values are identical.
    91  func (s AuxFields) Equal(other AuxFields) bool {
    92  	if len(s) != len(other) {
    93  		return false
    94  	}
    95  	for i := range s {
    96  		if !bytes.Equal(s[i], other[i]) {
    97  			return false
    98  		}
    99  	}
   100  	return true
   101  }