github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/topicsdb/topicsdb.go (about) 1 package topicsdb 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/unicornultrafoundation/go-helios/native/idx" 8 "github.com/unicornultrafoundation/go-helios/u2udb" 9 "github.com/unicornultrafoundation/go-u2u/common" 10 "github.com/unicornultrafoundation/go-u2u/core/types" 11 ) 12 13 const maxTopicsCount = 5 // count is limited hard to 5 by EVM (see LOG0...LOG4 ops) 14 15 var ( 16 ErrEmptyTopics = fmt.Errorf("empty topics") 17 ErrTooBigTopics = fmt.Errorf("too many topics") 18 ) 19 20 // Index is a specialized indexes for log records storing and fetching. 21 type Index interface { 22 FindInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash) (logs []*types.Log, err error) 23 ForEachInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash, onLog func(*types.Log) (gonext bool)) error 24 Push(recs ...*types.Log) error 25 Close() 26 27 WrapTablesAsBatched() (unwrap func()) 28 } 29 30 // New Index instance. 31 func New(dbs u2udb.DBProducer) Index { 32 tt := newIndex(dbs) 33 34 return tt 35 } 36 37 // New Index instance consumes limited threads count. 38 func NewWithThreadPool(dbs u2udb.DBProducer) Index { 39 tt := newIndex(dbs) 40 return &withThreadPool{tt} 41 } 42 43 func limitPattern(pattern [][]common.Hash) (limited [][]common.Hash, err error) { 44 if len(pattern) > (maxTopicsCount + 1) { 45 limited = make([][]common.Hash, (maxTopicsCount + 1)) 46 } else { 47 limited = make([][]common.Hash, len(pattern)) 48 } 49 copy(limited, pattern) 50 51 ok := false 52 for i, variants := range limited { 53 ok = ok || len(variants) > 0 54 if len(variants) > 1 { 55 limited[i] = uniqOnly(variants) 56 } 57 } 58 if !ok { 59 err = ErrEmptyTopics 60 return 61 } 62 63 return 64 } 65 66 func uniqOnly(hh []common.Hash) []common.Hash { 67 index := make(map[common.Hash]struct{}, len(hh)) 68 for _, h := range hh { 69 index[h] = struct{}{} 70 } 71 72 uniq := make([]common.Hash, 0, len(index)) 73 for h := range index { 74 uniq = append(uniq, h) 75 } 76 return uniq 77 }