github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/shipper/util/util.go (about)

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"runtime/debug"
     6  	"unsafe"
     7  
     8  	"go.etcd.io/bbolt"
     9  
    10  	"github.com/grafana/loki/pkg/storage/chunk/client/local"
    11  	"github.com/grafana/loki/pkg/storage/stores/series/index"
    12  )
    13  
    14  const sep = "\xff"
    15  
    16  func BuildIndexFileName(tableName, uploader, dbName string) string {
    17  	// Files are stored with <uploader>-<db-name>
    18  	objectKey := fmt.Sprintf("%s-%s", uploader, dbName)
    19  
    20  	// if the file is a migrated one then don't add its name to the object key otherwise we would re-upload them again here with a different name.
    21  	if tableName == dbName {
    22  		objectKey = uploader
    23  	}
    24  
    25  	return objectKey
    26  }
    27  
    28  type result struct {
    29  	boltdb *bbolt.DB
    30  	err    error
    31  }
    32  
    33  // SafeOpenBoltdbFile will recover from a panic opening a DB file, and return the panic message in the err return object.
    34  func SafeOpenBoltdbFile(path string) (*bbolt.DB, error) {
    35  	result := make(chan *result)
    36  	// Open the file in a separate goroutine because we want to change
    37  	// the behavior of a Fault for just this operation and not for the
    38  	// calling goroutine
    39  	go safeOpenBoltDbFile(path, result)
    40  	res := <-result
    41  	return res.boltdb, res.err
    42  }
    43  
    44  func safeOpenBoltDbFile(path string, ret chan *result) {
    45  	// boltdb can throw faults which are not caught by recover unless we turn them into panics
    46  	debug.SetPanicOnFault(true)
    47  	res := &result{}
    48  
    49  	defer func() {
    50  		if r := recover(); r != nil {
    51  			res.err = fmt.Errorf("recovered from panic opening boltdb file: %v", r)
    52  		}
    53  
    54  		// Return the result object on the channel to unblock the calling thread
    55  		ret <- res
    56  	}()
    57  
    58  	b, err := local.OpenBoltdbFile(path)
    59  	res.boltdb = b
    60  	res.err = err
    61  }
    62  
    63  func QueryKey(q index.Query) string {
    64  	ret := q.TableName + sep + q.HashValue
    65  
    66  	if len(q.RangeValuePrefix) != 0 {
    67  		ret += sep + string(q.RangeValuePrefix)
    68  	}
    69  
    70  	if len(q.RangeValueStart) != 0 {
    71  		ret += sep + string(q.RangeValueStart)
    72  	}
    73  
    74  	if len(q.ValueEqual) != 0 {
    75  		ret += sep + string(q.ValueEqual)
    76  	}
    77  
    78  	return ret
    79  }
    80  
    81  func GetUnsafeBytes(s string) []byte {
    82  	return *((*[]byte)(unsafe.Pointer(&s)))
    83  }
    84  
    85  func GetUnsafeString(buf []byte) string {
    86  	return *((*string)(unsafe.Pointer(&buf)))
    87  }