github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/neatptc/bloombits.go (about)

     1  package neatptc
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/neatlab/neatio/chain/core"
     7  	"github.com/neatlab/neatio/chain/core/bloombits"
     8  	"github.com/neatlab/neatio/chain/core/rawdb"
     9  	"github.com/neatlab/neatio/chain/core/types"
    10  	"github.com/neatlab/neatio/neatdb"
    11  	"github.com/neatlab/neatio/params"
    12  	"github.com/neatlab/neatio/utilities/common"
    13  	"github.com/neatlab/neatio/utilities/common/bitutil"
    14  )
    15  
    16  const (
    17  	bloomServiceThreads = 16
    18  
    19  	bloomFilterThreads = 3
    20  
    21  	bloomRetrievalBatch = 16
    22  
    23  	bloomRetrievalWait = time.Duration(0)
    24  )
    25  
    26  func (neatChain *NeatIO) startBloomHandlers() {
    27  	for i := 0; i < bloomServiceThreads; i++ {
    28  		go func() {
    29  			for {
    30  				select {
    31  				case <-neatChain.shutdownChan:
    32  					return
    33  
    34  				case request := <-neatChain.bloomRequests:
    35  					task := <-request
    36  					task.Bitsets = make([][]byte, len(task.Sections))
    37  					for i, section := range task.Sections {
    38  						head := rawdb.ReadCanonicalHash(neatChain.chainDb, (section+1)*params.BloomBitsBlocks-1)
    39  						if compVector, err := rawdb.ReadBloomBits(neatChain.chainDb, task.Bit, section, head); err == nil {
    40  							if blob, err := bitutil.DecompressBytes(compVector, int(params.BloomBitsBlocks)/8); err == nil {
    41  								task.Bitsets[i] = blob
    42  							} else {
    43  								task.Error = err
    44  							}
    45  						} else {
    46  							task.Error = err
    47  						}
    48  					}
    49  					request <- task
    50  				}
    51  			}
    52  		}()
    53  	}
    54  }
    55  
    56  const (
    57  	bloomConfirms = 256
    58  
    59  	bloomThrottling = 100 * time.Millisecond
    60  )
    61  
    62  type BloomIndexer struct {
    63  	size uint64
    64  
    65  	db  neatdb.Database
    66  	gen *bloombits.Generator
    67  
    68  	section uint64
    69  	head    common.Hash
    70  }
    71  
    72  func NewBloomIndexer(db neatdb.Database, size uint64) *core.ChainIndexer {
    73  	backend := &BloomIndexer{
    74  		db:   db,
    75  		size: size,
    76  	}
    77  	table := rawdb.NewTable(db, string(rawdb.BloomBitsIndexPrefix))
    78  
    79  	return core.NewChainIndexer(db, table, backend, size, bloomConfirms, bloomThrottling, "bloombits")
    80  }
    81  
    82  func (b *BloomIndexer) Reset(section uint64, lastSectionHead common.Hash) error {
    83  	gen, err := bloombits.NewGenerator(uint(b.size))
    84  	b.gen, b.section, b.head = gen, section, common.Hash{}
    85  	return err
    86  }
    87  
    88  func (b *BloomIndexer) Process(header *types.Header) {
    89  	b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom)
    90  	b.head = header.Hash()
    91  }
    92  
    93  func (b *BloomIndexer) Commit() error {
    94  	batch := b.db.NewBatch()
    95  	for i := 0; i < types.BloomBitLength; i++ {
    96  		bits, err := b.gen.Bitset(uint(i))
    97  		if err != nil {
    98  			return err
    99  		}
   100  		rawdb.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits))
   101  	}
   102  	return batch.Write()
   103  }