github.com/Schaudge/hts@v0.0.0-20240223063651-737b4d69d68c/bgzf/index/strategy.go (about) 1 // Copyright ©2015 The bíogo Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package index 6 7 import ( 8 "github.com/Schaudge/hts/bgzf" 9 ) 10 11 // MergeStrategy represents a chunk compression strategy. 12 type MergeStrategy func([]bgzf.Chunk) []bgzf.Chunk 13 14 var ( 15 // Identity leaves the []bgzf.Chunk unaltered. 16 Identity MergeStrategy = identity 17 18 // Adjacent merges contiguous bgzf.Chunks. 19 Adjacent MergeStrategy = adjacent 20 21 // Squash merges all bgzf.Chunks into a single bgzf.Chunk. 22 Squash MergeStrategy = squash 23 ) 24 25 // CompressorStrategy returns a MergeStrategy that will merge bgzf.Chunks 26 // that have a distance between BGZF block starts less than or equal 27 // to near. 28 func CompressorStrategy(near int64) MergeStrategy { 29 return func(chunks []bgzf.Chunk) []bgzf.Chunk { 30 if len(chunks) == 0 { 31 return nil 32 } 33 for c := 1; c < len(chunks); c++ { 34 leftChunk := chunks[c-1] 35 rightChunk := &chunks[c] 36 if leftChunk.End.File+near >= rightChunk.Begin.File { 37 rightChunk.Begin = leftChunk.Begin 38 if vOffset(leftChunk.End) > vOffset(rightChunk.End) { 39 rightChunk.End = leftChunk.End 40 } 41 chunks = append(chunks[:c-1], chunks[c:]...) 42 c-- 43 } 44 } 45 return chunks 46 } 47 } 48 49 func identity(chunks []bgzf.Chunk) []bgzf.Chunk { return chunks } 50 51 func adjacent(chunks []bgzf.Chunk) []bgzf.Chunk { 52 if len(chunks) == 0 { 53 return nil 54 } 55 for c := 1; c < len(chunks); c++ { 56 leftChunk := chunks[c-1] 57 rightChunk := &chunks[c] 58 leftEndOffset := vOffset(leftChunk.End) 59 if leftEndOffset >= vOffset(rightChunk.Begin) { 60 rightChunk.Begin = leftChunk.Begin 61 if leftEndOffset > vOffset(rightChunk.End) { 62 rightChunk.End = leftChunk.End 63 } 64 chunks = append(chunks[:c-1], chunks[c:]...) 65 c-- 66 } 67 } 68 return chunks 69 } 70 71 func squash(chunks []bgzf.Chunk) []bgzf.Chunk { 72 if len(chunks) == 0 { 73 return nil 74 } 75 left := chunks[0].Begin 76 right := chunks[0].End 77 for _, c := range chunks[1:] { 78 if vOffset(c.End) > vOffset(right) { 79 right = c.End 80 } 81 } 82 return []bgzf.Chunk{{Begin: left, End: right}} 83 }