github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/chunks/handle_blooms.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 "strings" 10 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 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) HandleBlooms(rCtx *output.RenderCtx, blockNums []base.Blknum) error { 20 chain := opts.Globals.Chain 21 22 fetchData := func(modelChan chan types.Modeler, errorChan chan error) { 23 showBloom := func(walker *walk.CacheWalker, path string, first bool) (bool, error) { 24 if path != index.ToBloomPath(path) { 25 return false, fmt.Errorf("should not happen in showBloom") 26 } 27 28 var bl index.Bloom 29 _ = bl.Read(path) 30 nInserted := 0 31 for _, bl := range bl.Blooms { 32 nInserted += int(bl.NInserted) 33 } 34 35 if opts.Globals.Verbose { 36 displayBloom(&bl, 1) 37 } 38 39 stats, err := GetChunkStats(chain, path) 40 if err != nil { 41 return false, err 42 } 43 44 rng, err := base.RangeFromFilenameE(path) 45 if err != nil { 46 return false, err 47 } 48 s := types.ChunkBloom{ 49 Magic: fmt.Sprintf("0x%x", bl.Header.Magic), 50 Hash: bl.Header.Hash, 51 Size: stats.BloomSz, 52 Range: rng.String(), 53 NBlooms: stats.NBlooms, 54 ByteWidth: index.BLOOM_WIDTH_IN_BYTES, 55 NInserted: uint64(nInserted), 56 } 57 rd := tslib.RangeToBounds(chain, &rng) 58 s.RangeDates = &rd 59 60 modelChan <- &s 61 return true, nil 62 } 63 64 walker := walk.NewCacheWalker( 65 chain, 66 opts.Globals.TestMode, 67 10, /* maxTests */ 68 showBloom, 69 ) 70 if err := walker.WalkBloomFilters(blockNums); err != nil { 71 errorChan <- err 72 rCtx.Cancel() 73 } 74 } 75 76 return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOpts()) 77 } 78 79 func displayBloom(bl *index.Bloom, verbose int) { 80 var bytesPerLine = (2048 / 16) /* 128 */ 81 if verbose > 0 && verbose <= 4 { 82 bytesPerLine = 32 83 } 84 85 nInserted := uint32(0) 86 for i := uint32(0); i < bl.Count; i++ { 87 nInserted += bl.Blooms[i].NInserted 88 } 89 fmt.Println("range:", bl.Range) 90 fmt.Println("nBlooms:", bl.Count) 91 fmt.Println("byteWidth:", index.BLOOM_WIDTH_IN_BYTES) 92 fmt.Println("nInserted:", nInserted) 93 if verbose > 0 { 94 for i := uint32(0); i < bl.Count; i++ { 95 for j := 0; j < len(bl.Blooms[i].Bytes); j++ { 96 if (j % bytesPerLine) == 0 { 97 if j != 0 { 98 fmt.Println() 99 } 100 } 101 ch := bl.Blooms[i].Bytes[j] 102 str := fmt.Sprintf("%08b", ch) 103 fmt.Printf("%s ", strings.Replace(str, "0", ".", -1)) 104 } 105 } 106 fmt.Println() 107 } 108 }