File: strategy.go

package info (click to toggle)
golang-github-biogo-hts 1.4.5%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,772 kB
  • sloc: makefile: 3
file content (83 lines) | stat: -rw-r--r-- 2,096 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright ©2015 The bíogo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package index

import (
	"github.com/biogo/hts/bgzf"
)

// MergeStrategy represents a chunk compression strategy.
type MergeStrategy func([]bgzf.Chunk) []bgzf.Chunk

var (
	// Identity leaves the []bgzf.Chunk unaltered.
	Identity MergeStrategy = identity

	// Adjacent merges contiguous bgzf.Chunks.
	Adjacent MergeStrategy = adjacent

	// Squash merges all bgzf.Chunks into a single bgzf.Chunk.
	Squash MergeStrategy = squash
)

// CompressorStrategy returns a MergeStrategy that will merge bgzf.Chunks
// that have a distance between BGZF block starts less than or equal
// to near.
func CompressorStrategy(near int64) MergeStrategy {
	return func(chunks []bgzf.Chunk) []bgzf.Chunk {
		if len(chunks) == 0 {
			return nil
		}
		for c := 1; c < len(chunks); c++ {
			leftChunk := chunks[c-1]
			rightChunk := &chunks[c]
			if leftChunk.End.File+near >= rightChunk.Begin.File {
				rightChunk.Begin = leftChunk.Begin
				if vOffset(leftChunk.End) > vOffset(rightChunk.End) {
					rightChunk.End = leftChunk.End
				}
				chunks = append(chunks[:c-1], chunks[c:]...)
				c--
			}
		}
		return chunks
	}
}

func identity(chunks []bgzf.Chunk) []bgzf.Chunk { return chunks }

func adjacent(chunks []bgzf.Chunk) []bgzf.Chunk {
	if len(chunks) == 0 {
		return nil
	}
	for c := 1; c < len(chunks); c++ {
		leftChunk := chunks[c-1]
		rightChunk := &chunks[c]
		leftEndOffset := vOffset(leftChunk.End)
		if leftEndOffset >= vOffset(rightChunk.Begin) {
			rightChunk.Begin = leftChunk.Begin
			if leftEndOffset > vOffset(rightChunk.End) {
				rightChunk.End = leftChunk.End
			}
			chunks = append(chunks[:c-1], chunks[c:]...)
			c--
		}
	}
	return chunks
}

func squash(chunks []bgzf.Chunk) []bgzf.Chunk {
	if len(chunks) == 0 {
		return nil
	}
	left := chunks[0].Begin
	right := chunks[0].End
	for _, c := range chunks[1:] {
		if vOffset(c.End) > vOffset(right) {
			right = c.End
		}
	}
	return []bgzf.Chunk{{Begin: left, End: right}}
}