<commit_before>// Copyright ©2014 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 tabix implements tabix coordinate sorted indexing.
package tabix

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"strings"

	"github.com/biogo/hts/bgzf"
	"github.com/biogo/hts/bgzf/index"
	"github.com/biogo/hts/internal"
	"github.com/biogo/hts/sam"
)

// Index is a tabix index.
type Index struct {
	Format    byte
	ZeroBased bool

	NameColumn  int32
	BeginColumn int32
	EndColumn   int32

	MetaChar rune
	Skip     int32

	refNames []string
	nameMap  map[string]int

	idx internal.Index
}

// New returns a new tabix index.
func NewTabix() *Index {
	return &Index{nameMap: make(map[string]int)}
}

// NumRefs returns the number of references in the index.
func (i *Index) NumRefs() int {
	return len(i.idx.Refs)
}

// Names returns the reference names in the index. The returned
// slice should not be altered.
func (i *Index) Names() []string {
	return i.refNames
}

// ReferenceStats returns the index statistics for the given reference and true
// if the statistics are valid.
func (i *Index) ReferenceStats(id int) (stats index.ReferenceStats, ok bool) {
	s := i.idx.Refs[id].Stats
	if s == nil {
		return index.ReferenceStats{}, false
	}
	return index.ReferenceStats(*s), true
}

// Unmapped returns the number of unmapped reads and true if the count is valid.
func (i *Index) Unmapped() (n uint64, ok bool) {
	if i.idx.Unmapped == nil {
		return 0, false
	}
	return *i.idx.Unmapped, true
}

// Record wraps types that may be indexed by an Index.
type Record interface {
	RefName() string
	Start() int
	End() int
}

type tabixShim struct {
	id, start, end int
}

func (r tabixShim) RefID() int { return r.id }
func (r tabixShim) Start() int { return r.start }
func (r tabixShim) End() int   { return r.end }

// Add records the SAM record as having being located at the given chunk.
func (i *Index) Add(r Record, c bgzf.Chunk, placed, mapped bool) error {
	refName := r.RefName()
	rid, ok := i.nameMap[refName]
	if !ok {
		rid = len(i.refNames)
		i.refNames = append(i.refNames, refName)
	}
	shim := tabixShim{id: rid, start: r.Start(), end: r.End()}
	return i.idx.Add(shim, internal.BinFor(r.Start(), r.End()), c, placed, mapped)
}

// Chunks returns a []bgzf.Chunk that corresponds to the given genomic interval.
func (i *Index) Chunks(r *sam.Reference, beg, end int) []bgzf.Chunk {
	chunks := i.idx.Chunks(r.ID(), beg, end)
	return adjacent(chunks)
}

var adjacent = index.Adjacent
<commit_msg>tabix.Index.Chunks now expects a record interface tabix: return nil with no results<commit_after>// Copyright ©2014 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 tabix implements tabix coordinate sorted indexing.
package tabix

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"strings"

	"github.com/biogo/hts/bgzf"
	"github.com/biogo/hts/bgzf/index"
	"github.com/biogo/hts/internal"
)

// Index is a tabix index.
type Index struct {
	Format    byte
	ZeroBased bool

	NameColumn  int32
	BeginColumn int32
	EndColumn   int32

	MetaChar rune
	Skip     int32

	refNames []string
	nameMap  map[string]int

	idx internal.Index
}

// New returns a new tabix index.
func NewTabix() *Index {
	return &Index{nameMap: make(map[string]int)}
}

// NumRefs returns the number of references in the index.
func (i *Index) NumRefs() int {
	return len(i.idx.Refs)
}

// Names returns the reference names in the index. The returned
// slice should not be altered.
func (i *Index) Names() []string {
	return i.refNames
}

// ReferenceStats returns the index statistics for the given reference and true
// if the statistics are valid.
func (i *Index) ReferenceStats(id int) (stats index.ReferenceStats, ok bool) {
	s := i.idx.Refs[id].Stats
	if s == nil {
		return index.ReferenceStats{}, false
	}
	return index.ReferenceStats(*s), true
}

// Unmapped returns the number of unmapped reads and true if the count is valid.
func (i *Index) Unmapped() (n uint64, ok bool) {
	if i.idx.Unmapped == nil {
		return 0, false
	}
	return *i.idx.Unmapped, true
}

// Record wraps types that may be indexed by an Index.
type Record interface {
	RefName() string
	Start() int
	End() int
}

type tabixShim struct {
	id, start, end int
}

func (r tabixShim) RefID() int { return r.id }
func (r tabixShim) Start() int { return r.start }
func (r tabixShim) End() int   { return r.end }

// Add records the SAM record as having being located at the given chunk.
func (i *Index) Add(r Record, c bgzf.Chunk, placed, mapped bool) error {
	refName := r.RefName()
	rid, ok := i.nameMap[refName]
	if !ok {
		rid = len(i.refNames)
		i.refNames = append(i.refNames, refName)
	}
	shim := tabixShim{id: rid, start: r.Start(), end: r.End()}
	return i.idx.Add(shim, internal.BinFor(r.Start(), r.End()), c, placed, mapped)
}

// Chunks returns a []bgzf.Chunk that corresponds to the given genomic interval.
func (i *Index) Chunks(r Record) []bgzf.Chunk {
	refName := r.RefName()
	id, ok := i.nameMap[refName]
	if !ok {
		return nil
	}
	chunks := i.idx.Chunks(id, r.Start(), r.End())
	return adjacent(chunks)
}

var adjacent = index.Adjacent

{'fraction_non_alphanumeric': 0.12, 'fraction_numerical': 0.005660377358490566, 'mean_word_length': 3.65, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3461245', 'n_tokens_mistral': 1899, 'n_tokens_neox': 1851, 'n_words': 652}