github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/index/bloom_read.go (about) 1 package index 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 "os" 8 "unsafe" 9 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" 13 ) 14 15 // Read reads the entire contents of the bloom filter 16 func (bl *Bloom) Read(fileName string) (err error) { 17 bl.Range, err = base.RangeFromFilenameE(fileName) 18 if err != nil { 19 return err 20 } 21 22 bl.File, err = os.OpenFile(fileName, os.O_RDONLY, 0644) 23 if err != nil { 24 return err 25 } 26 defer func() { 27 bl.File.Close() 28 bl.File = nil 29 }() 30 31 _, _ = bl.File.Seek(0, io.SeekStart) // already true, but can't hurt 32 if err = bl.readHeader(true /* check */); err != nil { // Note that it may not find a header, but it leaves the file pointer pointing to the count 33 return err 34 } 35 36 if err = binary.Read(bl.File, binary.LittleEndian, &bl.Count); err != nil { 37 return err 38 } 39 40 bl.Blooms = make([]bloomBytes, bl.Count) 41 for i := uint32(0); i < bl.Count; i++ { 42 if err = binary.Read(bl.File, binary.LittleEndian, &bl.Blooms[i].NInserted); err != nil { 43 return err 44 } 45 46 bl.Blooms[i].Bytes = make([]byte, BLOOM_WIDTH_IN_BYTES) 47 if err = binary.Read(bl.File, binary.LittleEndian, &bl.Blooms[i].Bytes); err != nil { 48 return err 49 } 50 } 51 52 return nil 53 } 54 55 // readHeader reads a bloom file header into Bloom. 56 func (bl *Bloom) readHeader(check bool) error { 57 58 // Set HeaderSize to 0. 59 bl.HeaderSize = 0 60 61 // Read header from file. 62 err := binary.Read(bl.File, binary.LittleEndian, &bl.Header) 63 if err != nil { 64 bl.Header = bloomHeader{} 65 _, _ = bl.File.Seek(0, io.SeekStart) 66 return err 67 } 68 69 // Check for unversioned bloom filter. 70 if bl.Header.Magic != file.SmallMagicNumber { 71 bl.Header = bloomHeader{} 72 _, _ = bl.File.Seek(0, io.SeekStart) 73 return fmt.Errorf("Bloom.readHeader: %w %x %x", ErrIncorrectMagic, bl.Header.Magic, file.SmallMagicNumber) 74 } 75 76 // Set HeaderSize. 77 bl.HeaderSize = int64(unsafe.Sizeof(bl.Header)) 78 79 // Validate hash against provided tag. 80 if check { 81 if bl.Header.Hash != base.BytesToHash(config.HeaderHash(config.ExpectedVersion())) { 82 return fmt.Errorf("Bloom.readHeader: %w %x %x", ErrIncorrectHash, bl.Header.Hash, base.BytesToHash(config.HeaderHash(config.ExpectedVersion()))) 83 } 84 } 85 86 return nil 87 }