func (cs *chkSelector) getPosBackward(ctx context.Context, pos journal.Pos) (chunk.Chunk, *chkStatus, journal.Pos, error) {
	cks, err := cs.jrnl.Chunks().Chunks(ctx)
	n := len(cks)
	if err != nil || n == 0 {
		return nil, nil, journal.Pos{}, err
	}
	idx := getChunkByIdOrLess(cks, pos.CId)
	var chk chunk.Chunk
	if idx == -1 {
		chk = cks[0]
		return nil, nil, journal.Pos{chk.Id(), 0}, nil
	}
	pIdx := pos.Idx
	if cks[idx].Id() != pos.CId {
		pIdx = cks[idx].Count() - 1
	}
	for ; idx >= 0; idx-- {
		chk = cks[idx]
		chkSt := cs.getChunkStatus(ctx, chk, cks)
		if pp, ok := chkSt.checkPosOrReduce(pIdx); ok {
			return chk, chkSt, journal.Pos{chk.Id(), pp}, nil
		}
		pIdx = math.MaxUint32
	}
	return nil, nil, journal.Pos{chk.Id(), 0}, nil
}
getPosBackward checks position and move it backward if it is needed. It also returns the chunk
which corresponds to the new position if it is changed.

If the next pos is less than the position of first record, it returns nil, nil, <first record of first chunk>, nil
If an error happens, it returns err != nil
package partition
import (
	"context"
	"github.com/logrange/logrange/pkg/model"
	"github.com/logrange/logrange/pkg/tmindex"
	"github.com/logrange/range/pkg/records/chunk"
	"github.com/logrange/range/pkg/records/journal"
	"math"
)
type (
	chkSelector struct {
		tmRange     model.TimeRange
		jrnl        journal.Journal
		tmidx       tmindex.TsIndexer
		tiRebuilder TmIndexRebuilder
		stats       map[chunk.Id]*chkStatus
	}
	chkStatus struct {
		minPos uint32
		maxPos uint32
		count  uint32
	}
)
func newChkSelector(tmRange model.TimeRange, jrnl journal.Journal, tmidx tmindex.TsIndexer, tiRebuilder TmIndexRebuilder) *chkSelector {
	cs := new(chkSelector)
	cs.tmRange = tmRange
	cs.jrnl = jrnl
	cs.tmidx = tmidx
	cs.tiRebuilder = tiRebuilder
	return cs
}
func (cs *chkSelector) getPosForward(ctx context.Context, pos journal.Pos) (chunk.Chunk, *chkStatus, journal.Pos, error) {
	cks, err := cs.jrnl.Chunks().Chunks(ctx)
	n := len(cks)
	if err != nil || n == 0 {
		return nil, nil, journal.Pos{}, err
	}
	idx := getChunkByIdOrGreater(cks, pos.CId)
	var chk chunk.Chunk
	if idx == n {
		chk = cks[idx-1]
		return nil, nil, journal.Pos{chk.Id(), chk.Count()}, nil
	}
	pIdx := pos.Idx
	if cks[idx].Id() != pos.CId {
		pIdx = 0
	}
	for ; idx < n; idx++ {
		chk = cks[idx]
		chkSt := cs.getChunkStatus(ctx, chk, cks)
		if np, ok := chkSt.checkPosOrAdvance(pIdx); ok {
			return chk, chkSt, journal.Pos{chk.Id(), np}, nil
		}
		pIdx = 0
	}
	return nil, nil, journal.Pos{chk.Id(), chk.Count()}, nil
}