github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/codec/decoder.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 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 codec 16 17 import ( 18 "encoding/binary" 19 "fmt" 20 21 "github.com/vescale/zgraph/datum" 22 "github.com/vescale/zgraph/parser/model" 23 "github.com/vescale/zgraph/types" 24 ) 25 26 // PropertyDecoder is used to decode value bytes into datum 27 type PropertyDecoder struct { 28 rowBytes 29 30 labels []*model.LabelInfo 31 properties []*model.PropertyInfo 32 } 33 34 func NewPropertyDecoder(labels []*model.LabelInfo, properties []*model.PropertyInfo) *PropertyDecoder { 35 return &PropertyDecoder{ 36 labels: labels, 37 properties: properties, 38 } 39 } 40 41 func (d *PropertyDecoder) Decode(rowData []byte) (map[uint16]struct{}, map[uint16]datum.Datum, error) { 42 err := d.fromBytes(rowData) 43 if err != nil { 44 return nil, nil, err 45 } 46 47 labelIDs := make(map[uint16]struct{}) 48 for _, label := range d.labels { 49 if d.hasLabel(uint16(label.ID)) { 50 labelIDs[uint16(label.ID)] = struct{}{} 51 } 52 } 53 54 row := make(map[uint16]datum.Datum) 55 for _, property := range d.properties { 56 idx := d.findProperty(property.ID) 57 if idx >= 0 { 58 propData := d.getData(idx) 59 d, err := d.decodeColDatum(propData) 60 if err != nil { 61 return nil, nil, err 62 } 63 row[property.ID] = d 64 } 65 } 66 67 return labelIDs, row, nil 68 } 69 70 func (d *PropertyDecoder) decodeColDatum(propData []byte) (datum.Datum, error) { 71 var value datum.Datum 72 typ := types.T(propData[0]) 73 switch typ { 74 case types.Int: 75 value = datum.NewInt(decodeInt(propData[1:])) 76 case types.Float: 77 _, v, err := DecodeFloat(propData[1:]) 78 if err != nil { 79 return nil, err 80 } 81 value = datum.NewFloat(v) 82 case types.String: 83 value = datum.NewString(string(propData[1:])) 84 case types.Date: 85 value = decodeDate(propData[1:]) 86 default: 87 // TODO: support more types 88 return value, fmt.Errorf("unknown type %s", typ) 89 } 90 return value, nil 91 } 92 93 func decodeInt(val []byte) int64 { 94 switch len(val) { 95 case 1: 96 return int64(int8(val[0])) 97 case 2: 98 return int64(int16(binary.LittleEndian.Uint16(val))) 99 case 4: 100 return int64(int32(binary.LittleEndian.Uint32(val))) 101 default: 102 return int64(binary.LittleEndian.Uint64(val)) 103 } 104 } 105 106 func decodeDate(val []byte) *datum.Date { 107 return datum.NewDateFromUnixEpochDays(int32(decodeInt(val))) 108 }