github.com/ledgerwatch/erigon-lib@v1.0.0/recsplit/index_reader.go (about)

     1  /*
     2     Copyright 2021 Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package recsplit
    18  
    19  import (
    20  	"sync"
    21  
    22  	"github.com/spaolacci/murmur3"
    23  )
    24  
    25  // IndexReader encapsulates Hash128 to allow concurrent access to Index
    26  type IndexReader struct {
    27  	hasher murmur3.Hash128
    28  	index  *Index
    29  	mu     sync.RWMutex
    30  }
    31  
    32  // NewIndexReader creates new IndexReader
    33  func NewIndexReader(index *Index) *IndexReader {
    34  	return &IndexReader{
    35  		hasher: murmur3.New128WithSeed(index.salt),
    36  		index:  index,
    37  	}
    38  }
    39  
    40  func (r *IndexReader) sum(key []byte) (uint64, uint64) {
    41  	r.mu.Lock()
    42  	defer r.mu.Unlock()
    43  	r.hasher.Reset()
    44  	r.hasher.Write(key) //nolint:errcheck
    45  	return r.hasher.Sum128()
    46  }
    47  
    48  func (r *IndexReader) sum2(key1, key2 []byte) (uint64, uint64) {
    49  	r.mu.Lock()
    50  	defer r.mu.Unlock()
    51  	r.hasher.Reset()
    52  	r.hasher.Write(key1) //nolint:errcheck
    53  	r.hasher.Write(key2) //nolint:errcheck
    54  	return r.hasher.Sum128()
    55  }
    56  
    57  // Lookup wraps index Lookup
    58  func (r *IndexReader) Lookup(key []byte) uint64 {
    59  	bucketHash, fingerprint := r.sum(key)
    60  	if r.index != nil {
    61  		return r.index.Lookup(bucketHash, fingerprint)
    62  	}
    63  	return 0
    64  }
    65  
    66  func (r *IndexReader) Lookup2(key1, key2 []byte) uint64 {
    67  	bucketHash, fingerprint := r.sum2(key1, key2)
    68  	if r.index != nil {
    69  		return r.index.Lookup(bucketHash, fingerprint)
    70  	}
    71  	return 0
    72  }
    73  
    74  func (r *IndexReader) Empty() bool {
    75  	return r.index.Empty()
    76  }
    77  
    78  func (r *IndexReader) Close() {
    79  	if r == nil || r.index == nil {
    80  		return
    81  	}
    82  	r.index.readers.Put(r)
    83  }