github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/operation/max.go (about)

     1  package operation
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/dgraph-io/badger/v2"
     9  
    10  	"github.com/onflow/flow-go/module/irrecoverable"
    11  	"github.com/onflow/flow-go/storage"
    12  )
    13  
    14  // maxKey is the biggest allowed key size in badger
    15  const maxKey = 65000
    16  
    17  // max holds the maximum length of keys in the database; in order to optimize
    18  // the end prefix of iteration, we need to know how many `0xff` bytes to add.
    19  var max uint32
    20  
    21  // we initialize max to maximum size, to detect if it wasn't set yet
    22  func init() {
    23  	max = maxKey
    24  }
    25  
    26  // InitMax retrieves the maximum key length to have it internally in the
    27  // package after restarting.
    28  // No errors are expected during normal operation.
    29  func InitMax(tx *badger.Txn) error {
    30  	key := makePrefix(codeMax)
    31  	item, err := tx.Get(key)
    32  	if errors.Is(err, badger.ErrKeyNotFound) { // just keep zero value as default
    33  		max = 0
    34  		return nil
    35  	}
    36  	if err != nil {
    37  		return fmt.Errorf("could not get max: %w", err)
    38  	}
    39  	_ = item.Value(func(val []byte) error {
    40  		max = binary.LittleEndian.Uint32(val)
    41  		return nil
    42  	})
    43  	return nil
    44  }
    45  
    46  // SetMax sets the value for the maximum key length used for efficient iteration.
    47  // No errors are expected during normal operation.
    48  func SetMax(tx storage.Transaction) error {
    49  	key := makePrefix(codeMax)
    50  	val := make([]byte, 4)
    51  	binary.LittleEndian.PutUint32(val, max)
    52  	err := tx.Set(key, val)
    53  	if err != nil {
    54  		return irrecoverable.NewExceptionf("could not set max: %w", err)
    55  	}
    56  	return nil
    57  }