Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
loki/pkg/storage/bloom/v1/bloom_querier.go

126 lines
2.2 KiB

package v1
import "github.com/pkg/errors"
type BloomQuerier interface {
Seek(BloomOffset) (*Bloom, error)
}
type LazyBloomIter struct {
b *Block
// state
initialized bool
err error
curPageIndex int
curPage *BloomPageDecoder
}
func NewLazyBloomIter(b *Block) *LazyBloomIter {
return &LazyBloomIter{
b: b,
}
}
func (it *LazyBloomIter) ensureInit() {
// TODO(owen-d): better control over when to decode
if !it.initialized {
if err := it.b.LoadHeaders(); err != nil {
it.err = err
}
it.initialized = true
}
}
func (it *LazyBloomIter) Seek(offset BloomOffset) {
it.ensureInit()
// if we need a different page or the current page hasn't been loaded,
// load the desired page
if it.curPageIndex != offset.Page || it.curPage == nil {
r, err := it.b.reader.Blooms()
if err != nil {
it.err = errors.Wrap(err, "getting blooms reader")
return
}
decoder, err := it.b.blooms.BloomPageDecoder(r, offset.Page)
if err != nil {
it.err = errors.Wrap(err, "loading bloom page")
return
}
it.curPageIndex = offset.Page
it.curPage = decoder
}
it.curPage.Seek(offset.ByteOffset)
}
func (it *LazyBloomIter) Next() bool {
it.ensureInit()
if it.err != nil {
return false
}
return it.next()
}
func (it *LazyBloomIter) next() bool {
if it.err != nil {
return false
}
for it.curPageIndex < len(it.b.blooms.pageHeaders) {
// first access of next page
if it.curPage == nil {
r, err := it.b.reader.Blooms()
if err != nil {
it.err = errors.Wrap(err, "getting blooms reader")
return false
}
it.curPage, err = it.b.blooms.BloomPageDecoder(
r,
it.curPageIndex,
)
if err != nil {
it.err = err
return false
}
continue
}
if !it.curPage.Next() {
// there was an error
if it.curPage.Err() != nil {
return false
}
// we've exhausted the current page, progress to next
it.curPageIndex++
it.curPage = nil
continue
}
return true
}
// finished last page
return false
}
func (it *LazyBloomIter) At() *Bloom {
return it.curPage.At()
}
func (it *LazyBloomIter) Err() error {
{
if it.err != nil {
return it.err
}
if it.curPage != nil {
return it.curPage.Err()
}
return nil
}
}