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 }