Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ build-image:
-t ${IMAGE}:${VERSION} \
.

.PHONY: build
build:
CGO_ENABLED=1 \
go build -tags 'netgo osusergo' \
-o ${LOCAL_BIN}/${OS}-${ARCH}/ \
./cmd/...

.PHONY: build-debug
build-debug:
CGO_ENABLED=0 \
Expand All @@ -30,7 +37,7 @@ build-debug:
./cmd/...

.PHONY: run
run: build-debug
run: build
SEQDB_STORAGE_DATA_DIR=$(shell mktemp -d) \
${LOCAL_BIN}/${OS}-${ARCH}/seq-db \
--mode=single \
Expand Down
29 changes: 16 additions & 13 deletions frac/active.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ type Active struct {
DocsPositions *DocsPositions
IDsToLIDs *ActiveLIDs

docsFile *os.File
docsReader storage.DocsReader
sortReader storage.DocsReader
docsCache *cache.ConcurrentCache[[]byte]
sortCache *cache.ConcurrentCache[[]byte]
docsFile *os.File
docsCache *cache.ConcurrentCache[[]byte]
sortCache *cache.ConcurrentCache[[]byte]

readLimiter *storage.ReadLimiter

walFile *os.File
walReader *storage.WalReader
Expand Down Expand Up @@ -81,11 +81,11 @@ func NewActive(
RIDs: NewIDs(),
DocBlocks: NewIDs(),

docsFile: docsFile,
docsCache: docsCache,
sortCache: sortCache,
docsReader: storage.NewDocsReader(readLimiter, docsFile, docsCache),
sortReader: storage.NewDocsReader(readLimiter, docsFile, sortCache),
docsFile: docsFile,
docsCache: docsCache,
sortCache: sortCache,

readLimiter: readLimiter,

walFile: walFile,
walReader: walReader,
Expand Down Expand Up @@ -357,10 +357,13 @@ func (f *Active) createDataProvider(ctx context.Context) *activeDataProvider {
rids: f.RIDs,
tokenList: f.TokenList,

blocksOffsets: f.DocBlocks.GetVals(),
docsPositions: f.DocsPositions,
idsToLids: f.IDsToLIDs,
docsReader: &f.docsReader,
docsPositions: f.DocsPositions,

docsReader: storage.NewDocsReader(
f.readLimiter, f.docsFile,
f.docsCache, f.DocBlocks.GetVals(),
),

skipMaskProvider: f.skipMaskProvider,
}
Expand Down
15 changes: 4 additions & 11 deletions frac/active_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ type activeDataProvider struct {

tokenList *TokenList

blocksOffsets []uint64
docsPositions *DocsPositions
idsToLids *ActiveLIDs
docsReader *storage.DocsReader
docsReader storage.DocsReader

idsIndex *activeIDsIndex

Expand Down Expand Up @@ -79,10 +78,9 @@ func (dp *activeDataProvider) Fetch(ids []seq.ID, noSkipMasks bool) ([][]byte, e
res := make([][]byte, len(ids))

indexes := []activeFetchIndex{{
blocksOffsets: dp.blocksOffsets,
docsPositions: dp.docsPositions,
idsToLids: dp.idsToLids,
docsReader: dp.docsReader,
docsReader: &dp.docsReader,
skipMaskProvider: dp.skipMaskProvider,
fracName: dp.info.Name(),
}}
Expand Down Expand Up @@ -295,18 +293,13 @@ func inverseLIDs(unmapped []uint32, inv *inverser, minLID, maxLID uint32) []uint
}

type activeFetchIndex struct {
blocksOffsets []uint64
docsPositions *DocsPositions
idsToLids *ActiveLIDs
docsReader *storage.DocsReader
skipMaskProvider skipMaskProvider
fracName string
}

func (di *activeFetchIndex) GetBlocksOffsets(num uint32) uint64 {
return di.blocksOffsets[num]
}

func (di *activeFetchIndex) GetDocPos(ids []seq.ID, noSkipMasks bool) ([]seq.DocPos, error) {
docsPos := make([]seq.DocPos, len(ids))
for i, id := range ids {
Expand Down Expand Up @@ -343,6 +336,6 @@ func (di *activeFetchIndex) GetDocPos(ids []seq.ID, noSkipMasks bool) ([]seq.Doc
return docsPos, nil
}

func (di *activeFetchIndex) ReadDocs(blockOffset uint64, docOffsets []uint64) ([][]byte, error) {
return di.docsReader.ReadDocs(blockOffset, docOffsets)
func (di *activeFetchIndex) ReadDocs(blockIndex uint32, docOffsets []uint64) ([][]byte, error) {
return di.docsReader.ReadDocs(blockIndex, docOffsets)
}
9 changes: 5 additions & 4 deletions frac/active_sealing_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type ActiveSealingSource struct {

docPosMap map[seq.ID]seq.DocPos // Original document positions
docPosSorted []seq.DocPos // Document positions after sorting
docsReader *storage.DocsReader // Document storage reader
docsReader storage.DocsReader // Document storage reader
}

func NewActiveSealingSource(active *Active, params common.SealParams) (*ActiveSealingSource, error) {
Expand Down Expand Up @@ -79,7 +79,9 @@ func NewActiveSealingSource(active *Active, params common.SealParams) (*ActiveSe

docPosMap: active.DocsPositions.idToPos,
blocksOffsets: active.DocBlocks.vals,
docsReader: &active.sortReader,
docsReader: storage.NewDocsReader(
active.readLimiter, active.docsFile, active.sortCache, active.DocBlocks.vals,
),
}

src.prepareInfo()
Expand Down Expand Up @@ -265,11 +267,10 @@ func (src *ActiveSealingSource) Docs() iter.Seq2[Document, error] {
// doc reads a document from storage by its position.
func (src *ActiveSealingSource) doc(pos seq.DocPos) ([]byte, error) {
blockIndex, docOffset := pos.Unpack()
blockOffset := src.blocksOffsets[blockIndex]

var doc []byte
err := src.docsReader.ReadDocsFunc(
blockOffset, []uint64{docOffset},
blockIndex, []uint64{docOffset},
func(b []byte) error {
doc = b
return nil
Expand Down
5 changes: 2 additions & 3 deletions frac/processor/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import (
)

type fetchIndex interface {
GetBlocksOffsets(uint32) uint64
GetDocPos([]seq.ID, bool) ([]seq.DocPos, error)
ReadDocs(blockOffset uint64, docOffsets []uint64) ([][]byte, error)
ReadDocs(blockIndex uint32, docOffsets []uint64) ([][]byte, error)
}

func IndexFetch(ids []seq.ID, noSkipMasks bool, sw *stopwatch.Stopwatch, fetchIndex fetchIndex, res [][]byte) error {
Expand All @@ -22,7 +21,7 @@ func IndexFetch(ids []seq.ID, noSkipMasks bool, sw *stopwatch.Stopwatch, fetchIn

m = sw.Start("read_doc")
for i, docOffsets := range offsets {
docs, err := fetchIndex.ReadDocs(fetchIndex.GetBlocksOffsets(blocks[i]), docOffsets)
docs, err := fetchIndex.ReadDocs(blocks[i], docOffsets)
if err != nil {
return err
}
Expand Down
21 changes: 12 additions & 9 deletions frac/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ type Remote struct {

info *common.Info

docsFile storage.ImmutableFile
docsCache *cache.ConcurrentCache[[]byte]
docsReader storage.DocsReader
docsFile storage.ImmutableFile
docsCache *cache.ConcurrentCache[[]byte]

// IsLegacy is true for fractions that use the old single .index file format.
IsLegacy bool
Expand Down Expand Up @@ -170,10 +169,9 @@ func (f *Remote) createDataProvider(ctx context.Context) (*sealedDataProvider, e
ctx: ctx,
fractionTypeLabel: "remote",

info: f.info,
config: f.Config,
docsReader: &f.docsReader,
blocksOffsets: f.blocksData.BlocksOffsets,
info: f.info,
config: f.Config,
docsReader: f.docsReader(),

lidsTable: f.blocksData.LIDsTable,
lidsLoader: lids.NewLoader(f.info.BinaryDataVer, &ir.LID, cache.NewSession(f.indexCache.LIDs)),
Expand Down Expand Up @@ -226,6 +224,13 @@ func (f *Remote) indexReaders() IndexReaders {
}
}

func (f *Remote) docsReader() storage.DocsReader {
return storage.NewDocsReader(
f.readLimiter, f.docsFile,
f.docsCache, f.blocksData.BlocksOffsets,
)
}

func (f *Remote) Info() *common.Info {
return f.info
}
Expand Down Expand Up @@ -454,7 +459,6 @@ func (f *Remote) openDocs() error {

if unsortedExists {
f.docsFile = s3.NewReader(f.ctx, f.s3cli, unsortedName)
f.docsReader = storage.NewDocsReader(f.readLimiter, f.docsFile, f.docsCache)
return nil
}

Expand All @@ -468,7 +472,6 @@ func (f *Remote) openDocs() error {

if sortedExists {
f.docsFile = s3.NewReader(f.ctx, f.s3cli, sortedName)
f.docsReader = storage.NewDocsReader(f.readLimiter, f.docsFile, f.docsCache)
return nil
}

Expand Down
21 changes: 12 additions & 9 deletions frac/sealed.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ type Sealed struct {

info *common.Info

docsFile *os.File
docsCache *cache.ConcurrentCache[[]byte]
docsReader storage.DocsReader
docsFile *os.File
docsCache *cache.ConcurrentCache[[]byte]

// IsLegacy is true for fractions that use the old single .index file format.
IsLegacy bool
Expand Down Expand Up @@ -258,8 +257,6 @@ func (f *Sealed) openDocs() {
)
}
}

f.docsReader = storage.NewDocsReader(f.readLimiter, f.docsFile, f.docsCache)
}

func (f *Sealed) loadInfo() {
Expand Down Expand Up @@ -499,10 +496,9 @@ func (f *Sealed) createDataProvider(ctx context.Context) *sealedDataProvider {
ctx: ctx,
fractionTypeLabel: "sealed",

info: f.info,
config: f.Config,
docsReader: &f.docsReader,
blocksOffsets: f.blocksData.BlocksOffsets,
info: f.info,
config: f.Config,
docsReader: f.docsReader(),

lidsTable: f.blocksData.LIDsTable,
lidsLoader: lids.NewLoader(f.info.BinaryDataVer, &ir.LID, cache.NewSession(f.indexCache.LIDs)),
Expand Down Expand Up @@ -568,6 +564,13 @@ func (f *Sealed) indexReaders() IndexReaders {
}
}

func (f *Sealed) docsReader() storage.DocsReader {
return storage.NewDocsReader(
f.readLimiter, f.docsFile,
f.docsCache, f.blocksData.BlocksOffsets,
)
}

// computeIndexOnDisk returns the total on-disk size of index files for a local fraction.
func (f *Sealed) computeIndexSize() {
suffixes := []string{
Expand Down
15 changes: 4 additions & 11 deletions frac/sealed_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ type sealedDataProvider struct {
tokenBlockLoader *token.BlockLoader
tokenTableLoader *token.TableLoader

blocksOffsets []uint64
docsReader *storage.DocsReader
docsReader storage.DocsReader

// fractionTypeLabel can be either 'sealed' or 'remote'.
// This value is used in metrics to distinguish between operations over local and remote fractions.
Expand All @@ -65,8 +64,7 @@ func (dp *sealedDataProvider) getFetchIndex() *sealedFetchIndex {
return &sealedFetchIndex{
fracName: dp.info.Name(),
idsIndex: dp.getIDsIndex(),
docsReader: dp.docsReader,
blocksOffsets: dp.blocksOffsets,
docsReader: &dp.docsReader,
skipMaskProvider: dp.skipMaskProvider,
}
}
Expand Down Expand Up @@ -362,14 +360,9 @@ type sealedFetchIndex struct {
fracName string
idsIndex *sealedIDsIndex
docsReader *storage.DocsReader
blocksOffsets []uint64
skipMaskProvider skipMaskProvider
}

func (fi *sealedFetchIndex) GetBlocksOffsets(num uint32) uint64 {
return fi.blocksOffsets[num]
}

func (fi *sealedFetchIndex) GetDocPos(ids []seq.ID, noSkipMasks bool) ([]seq.DocPos, error) {
allLids := fi.findLIDs(ids)

Expand Down Expand Up @@ -406,8 +399,8 @@ func (fi *sealedFetchIndex) GetDocPos(ids []seq.ID, noSkipMasks bool) ([]seq.Doc
return fi.getDocPosByLIDs(allLids), nil
}

func (fi *sealedFetchIndex) ReadDocs(blockOffset uint64, docOffsets []uint64) ([][]byte, error) {
return fi.docsReader.ReadDocs(blockOffset, docOffsets)
func (fi *sealedFetchIndex) ReadDocs(blockIndex uint32, docOffsets []uint64) ([][]byte, error) {
return fi.docsReader.ReadDocs(blockIndex, docOffsets)
}

// findLIDs returns a slice of LIDs. If seq.ID is not found, LID has the value 0 at the corresponding position
Expand Down
36 changes: 26 additions & 10 deletions storage/docs_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,28 @@ import (
)

type DocsReader struct {
reader DocBlocksReader
cache *cache.ConcurrentCache[[]byte]
reader DocBlocksReader
cache *cache.ConcurrentCache[[]byte]
blockOffsets []uint64
}

func NewDocsReader(limiter *ReadLimiter, reader io.ReaderAt, docsCache *cache.ConcurrentCache[[]byte]) DocsReader {
func NewDocsReader(
limiter *ReadLimiter,
reader io.ReaderAt,
docsCache *cache.ConcurrentCache[[]byte],
blockOffsets []uint64,
) DocsReader {
return DocsReader{
reader: NewDocBlocksReader(limiter, reader),
cache: docsCache,
reader: NewDocBlocksReader(limiter, reader),
cache: docsCache,
blockOffsets: blockOffsets,
}
}

func (r *DocsReader) ReadDocs(blockOffset uint64, docOffsets []uint64) ([][]byte, error) {
func (r *DocsReader) ReadDocs(blockIndex uint32, docOffsets []uint64) ([][]byte, error) {
bufSize := 0
res := make([][]byte, 0, len(docOffsets))
err := r.ReadDocsFunc(blockOffset, docOffsets, func(doc []byte) error {
err := r.ReadDocsFunc(blockIndex, docOffsets, func(doc []byte) error {
bufSize += len(doc)
res = append(res, doc)
return nil
Expand All @@ -41,16 +48,25 @@ func (r *DocsReader) ReadDocs(blockOffset uint64, docOffsets []uint64) ([][]byte
return res, nil
}

func (r *DocsReader) Load(blockOffset uint32) ([]byte, int, error) {
func (r *DocsReader) Load(blockIndex uint32) ([]byte, int, error) {
if uint64(blockIndex) >= uint64(len(r.blockOffsets)) {
return nil, 0, fmt.Errorf(
"doc block index %d is out of range [0, %d)",
blockIndex, len(r.blockOffsets),
)
}

blockOffset := r.blockOffsets[blockIndex]
block, _, err := r.reader.ReadDocBlockPayload(int64(blockOffset))
if err != nil {
return nil, 0, fmt.Errorf("can't fetch doc at pos %d: %w", blockOffset, err)
}

return block, cap(block), nil
}

func (r *DocsReader) ReadDocsFunc(blockOffset uint64, docOffsets []uint64, cb func([]byte) error) error {
block, err := r.cache.Get(uint32(blockOffset), r)
func (r *DocsReader) ReadDocsFunc(blockIndex uint32, docOffsets []uint64, cb func([]byte) error) error {
block, err := r.cache.Get(blockIndex, r)
if err != nil {
return err
}
Expand Down
Loading