github.com/aaabigfish/gopkg@v1.1.0/cloud/metainfo/utils.go (about) 1 // Copyright 2021 ByteDance Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package metainfo 16 17 import ( 18 "context" 19 "strings" 20 ) 21 22 // HasMetaInfo detects whether the given context contains metainfo. 23 func HasMetaInfo(ctx context.Context) bool { 24 return getNode(ctx) != nil 25 } 26 27 // SetMetaInfoFromMap retrieves metainfo key-value pairs from the given map and sets then into the context. 28 // Only those keys with prefixes defined in this module would be used. 29 // If the context has been carrying metanifo pairs, they will be merged as a basis. 30 func SetMetaInfoFromMap(ctx context.Context, m map[string]string) context.Context { 31 if ctx == nil { 32 return nil 33 } 34 35 if len(m) == 0 { 36 return ctx 37 } 38 39 var mv *mapView 40 if x := getNode(ctx); x != nil { 41 mv = x.mapView() 42 } else { 43 mv = newMapView() 44 } 45 46 for k, v := range m { 47 if len(k) == 0 || len(v) == 0 { 48 continue 49 } 50 51 switch { 52 case strings.HasPrefix(k, PrefixTransientUpstream): 53 if len(k) > lenPTU { // do not move this condition to the case statement to prevent a PTU matches PT 54 mv.stale[k[lenPTU:]] = v 55 } 56 case strings.HasPrefix(k, PrefixTransient): 57 if len(k) > lenPT { 58 mv.transient[k[lenPT:]] = v 59 } 60 case strings.HasPrefix(k, PrefixPersistent): 61 if len(k) > lenPP { 62 mv.persistent[k[lenPP:]] = v 63 } 64 } 65 } 66 67 if mv.size() == 0 { 68 // TODO: remove this? 69 return ctx 70 } 71 72 return withNode(ctx, mv.toNode()) 73 } 74 75 // SaveMetaInfoToMap set key-value pairs from ctx to m while filtering out transient-upstream data. 76 func SaveMetaInfoToMap(ctx context.Context, m map[string]string) { 77 if ctx == nil || m == nil { 78 return 79 } 80 ctx = TransferForward(ctx) 81 for k, v := range GetAllValues(ctx) { 82 m[PrefixTransient+k] = v 83 } 84 for k, v := range GetAllPersistentValues(ctx) { 85 m[PrefixPersistent+k] = v 86 } 87 } 88 89 // sliceToMap converts a kv slice to map. If the slice is empty, an empty map will be returned instead of nil. 90 func sliceToMap(slice []kv) (m map[string]string) { 91 if size := len(slice); size == 0 { 92 m = make(map[string]string) 93 } else { 94 m = make(map[string]string, size) 95 } 96 for _, kv := range slice { 97 m[kv.key] = kv.val 98 } 99 return 100 } 101 102 // mapToSlice converts a map to a kv slice. If the map is empty, the return value will be nil. 103 func mapToSlice(kvs map[string]string) (slice []kv) { 104 size := len(kvs) 105 if size == 0 { 106 return 107 } 108 slice = make([]kv, 0, size) 109 for k, v := range kvs { 110 slice = append(slice, kv{key: k, val: v}) 111 } 112 return 113 }