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 }