kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/serving/graph/columnar/columnar_encoding.go (about) 1 /* 2 * Copyright 2018 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this src 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 columnar implements the columnar table format for a Kythe xrefs service. 18 package columnar // import "kythe.io/kythe/go/serving/graph/columnar" 19 20 import ( 21 "fmt" 22 23 "kythe.io/kythe/go/util/keys" 24 25 "google.golang.org/protobuf/proto" 26 27 gspb "kythe.io/kythe/proto/graph_serving_go_proto" 28 scpb "kythe.io/kythe/proto/schema_go_proto" 29 spb "kythe.io/kythe/proto/storage_go_proto" 30 ) 31 32 var ( 33 // EdgesKeyPrefix is the common key prefix for all Kythe columnar Edges 34 // key-value entries. 35 EdgesKeyPrefix, _ = keys.Append(nil, "eg") 36 ) 37 38 func init() { 39 // Restrict the capacity of the key prefix to ensure appending to it creates a new array. 40 EdgesKeyPrefix = EdgesKeyPrefix[:len(EdgesKeyPrefix):len(EdgesKeyPrefix)] 41 } 42 43 // Columnar edges group numbers. 44 // See: kythe/proto/graph_serving.proto 45 const ( 46 columnarEdgesIndexGroup = -1 // no group number 47 columnarEdgesEdgeGroup = 10 48 columnarEdgesTargetGroup = 20 49 ) 50 51 // KV is a single columnar key-value entry. 52 type KV struct{ Key, Value []byte } 53 54 // EncodeEdgesEntry encodes a columnar Edges entry. 55 func EncodeEdgesEntry(keyPrefix []byte, eg *gspb.Edges) (*KV, error) { 56 switch e := eg.Entry.(type) { 57 case *gspb.Edges_Index_: 58 return encodeEdgesIndex(keyPrefix, eg.Source, e.Index) 59 case *gspb.Edges_Edge_: 60 return encodeEdge(keyPrefix, eg.Source, e.Edge) 61 case *gspb.Edges_Target_: 62 return encodeEdgesTarget(keyPrefix, eg.Source, e.Target) 63 default: 64 return nil, fmt.Errorf("unknown Edges entry: %T", e) 65 } 66 } 67 68 func encodeEdgesIndex(prefix []byte, src *spb.VName, idx *gspb.Edges_Index) (*KV, error) { 69 key, err := keys.Append(prefix, src) 70 if err != nil { 71 return nil, err 72 } 73 val, err := proto.Marshal(idx) 74 if err != nil { 75 return nil, err 76 } 77 return &KV{key, val}, nil 78 } 79 80 func encodeEdge(prefix []byte, src *spb.VName, e *gspb.Edges_Edge) (*KV, error) { 81 key, err := keys.Append(prefix, src, columnarEdgesEdgeGroup, 82 e.GetGenericKind(), int32(e.GetKytheKind()), e.Ordinal, e.Reverse, e.Target) 83 if err != nil { 84 return nil, err 85 } 86 val, err := proto.Marshal(&gspb.Edges_Edge{}) 87 if err != nil { 88 return nil, err 89 } 90 return &KV{key, val}, nil 91 } 92 93 func encodeEdgesTarget(prefix []byte, src *spb.VName, t *gspb.Edges_Target) (*KV, error) { 94 key, err := keys.Append(prefix, src, columnarEdgesTargetGroup, t.Node.Source) 95 if err != nil { 96 return nil, err 97 } 98 val, err := proto.Marshal(t) 99 if err != nil { 100 return nil, err 101 } 102 return &KV{key, val}, nil 103 } 104 105 // DecodeEdgesEntry decodes a columnar Edges entry. 106 func DecodeEdgesEntry(src *spb.VName, key string, val []byte) (*gspb.Edges, error) { 107 kind := columnarEdgesIndexGroup 108 if key != "" { 109 var err error 110 key, err = keys.Parse(key, &kind) 111 if err != nil { 112 return nil, fmt.Errorf("invalid Edges group kind: %v", err) 113 } 114 } 115 switch kind { 116 case columnarEdgesIndexGroup: 117 return decodeEdgesIndex(src, key, val) 118 case columnarEdgesEdgeGroup: 119 return decodeEdge(src, key, val) 120 case columnarEdgesTargetGroup: 121 return decodeEdgesTarget(src, key, val) 122 default: 123 return nil, fmt.Errorf("unknown group kind: %d", kind) 124 } 125 } 126 127 func decodeEdgesIndex(src *spb.VName, key string, val []byte) (*gspb.Edges, error) { 128 var idx gspb.Edges_Index 129 if err := proto.Unmarshal(val, &idx); err != nil { 130 return nil, err 131 } 132 return &gspb.Edges{ 133 Source: src, 134 Entry: &gspb.Edges_Index_{&idx}, 135 }, nil 136 } 137 138 func decodeEdge(src *spb.VName, key string, val []byte) (*gspb.Edges, error) { 139 var ( 140 genericKind string 141 kytheKind int32 142 ordinal int32 143 reverse bool 144 target spb.VName 145 ) 146 key, err := keys.Parse(key, &genericKind, &kytheKind, &ordinal, &reverse, &target) 147 if err != nil { 148 return nil, err 149 } 150 var e gspb.Edges_Edge 151 if err := proto.Unmarshal(val, &e); err != nil { 152 return nil, err 153 } 154 e.Reverse = reverse 155 e.Ordinal = ordinal 156 e.Target = &target 157 if genericKind != "" { 158 e.Kind = &gspb.Edges_Edge_GenericKind{genericKind} 159 } else { 160 e.Kind = &gspb.Edges_Edge_KytheKind{scpb.EdgeKind(kytheKind)} 161 } 162 return &gspb.Edges{ 163 Source: src, 164 Entry: &gspb.Edges_Edge_{&e}, 165 }, nil 166 } 167 168 func decodeEdgesTarget(src *spb.VName, key string, val []byte) (*gspb.Edges, error) { 169 var tgt gspb.Edges_Target 170 if err := proto.Unmarshal(val, &tgt); err != nil { 171 return nil, err 172 } 173 return &gspb.Edges{ 174 Source: src, 175 Entry: &gspb.Edges_Target_{&tgt}, 176 }, nil 177 }