github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/chunks/handle_index.go (about)

     1  // Copyright 2021 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  
     5  package chunksPkg
     6  
     7  import (
     8  	"fmt"
     9  
    10  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
    11  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file"
    12  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/index"
    13  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output"
    14  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/tslib"
    15  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
    16  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk"
    17  )
    18  
    19  func (opts *ChunksOptions) HandleIndex(rCtx *output.RenderCtx, blockNums []base.Blknum) error {
    20  	if len(opts.Belongs) > 0 {
    21  		return opts.HandleIndexBelongs(rCtx, blockNums)
    22  	}
    23  
    24  	chain := opts.Globals.Chain
    25  	fetchData := func(modelChan chan types.Modeler, errorChan chan error) {
    26  		showIndex := func(walker *walk.CacheWalker, fileName string, first bool) (bool, error) {
    27  			if fileName != index.ToBloomPath(fileName) {
    28  				return false, fmt.Errorf("should not happen in showIndex")
    29  			}
    30  
    31  			fileName = index.ToIndexPath(fileName)
    32  			if !file.FileExists(fileName) {
    33  				// Bloom files exist, but index files don't. It's okay.
    34  				return true, nil
    35  			}
    36  
    37  			indexChunk, err := index.OpenIndex(fileName, true /* check */)
    38  			if err != nil {
    39  				return false, err
    40  			}
    41  			defer indexChunk.File.Close()
    42  
    43  			rng, err := base.RangeFromFilenameE(fileName)
    44  			if err != nil {
    45  				return false, err
    46  			}
    47  
    48  			s := types.ChunkIndex{
    49  				Range:        rng.String(),
    50  				Magic:        fmt.Sprintf("0x%x", indexChunk.Header.Magic),
    51  				Hash:         indexChunk.Header.Hash,
    52  				NAddresses:   uint64(indexChunk.Header.AddressCount),
    53  				NAppearances: uint64(indexChunk.Header.AppearanceCount),
    54  				Size:         uint64(file.FileSize(fileName)),
    55  			}
    56  			rd := tslib.RangeToBounds(chain, &rng)
    57  			s.RangeDates = &rd
    58  
    59  			modelChan <- &s
    60  			return true, nil
    61  		}
    62  
    63  		walker := walk.NewCacheWalker(
    64  			chain,
    65  			opts.Globals.TestMode,
    66  			100, /* maxTests */
    67  			showIndex,
    68  		)
    69  		if err := walker.WalkBloomFilters(blockNums); err != nil {
    70  			errorChan <- err
    71  			rCtx.Cancel()
    72  		}
    73  	}
    74  
    75  	return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOpts())
    76  }