@@ -87,41 +87,63 @@ func serializeEntityKey(entityKey *types.EntityKey, entityKeySerializationVersio
8787 }
8888
8989 keys := make ([]string , 0 , len (m ))
90- for k := range entityKey .JoinKeys {
91- keys = append (keys , entityKey .JoinKeys [k ])
92- }
93- sort .Strings (keys )
90+ keys = append (keys , entityKey .JoinKeys ... )
91+ sort .Strings (keys ) // Sort the keys
9492
9593 // Build the key
96- length := 5 * len (keys )
94+ length := 7 * len (keys )
9795 bufferList := make ([][]byte , length )
96+ offset := 0
97+
98+ // For entityKeySerializationVersion 3 and above, we add the number of join keys
99+ // as the first 4 bytes of the serialized key.
100+ if entityKeySerializationVersion >= 3 {
101+ byteBuffer := make ([]byte , 4 )
102+ binary .LittleEndian .PutUint32 (byteBuffer , uint32 (len (keys )))
103+ bufferList [offset ] = byteBuffer // First buffer is always the length of the keys
104+ offset ++
105+ }
98106
99107 for i := 0 ; i < len (keys ); i ++ {
100- offset := i * 2
108+ // Add the key type STRING info
101109 byteBuffer := make ([]byte , 4 )
102110 binary .LittleEndian .PutUint32 (byteBuffer , uint32 (types .ValueType_Enum_value ["STRING" ]))
103111 bufferList [offset ] = byteBuffer
104- bufferList [offset + 1 ] = []byte (keys [i ])
112+ offset ++
113+
114+ // Add the size of current "key" string
115+ keyLenByteBuffer := make ([]byte , 4 )
116+ binary .LittleEndian .PutUint32 (keyLenByteBuffer , uint32 (len (keys [i ])))
117+ bufferList [offset ] = keyLenByteBuffer
118+ offset ++
119+
120+ // Add value
121+ bufferList [offset ] = []byte (keys [i ])
122+ offset ++
105123 }
106124
107125 for i := 0 ; i < len (keys ); i ++ {
108- offset := (2 * len (keys )) + (i * 3 )
109126 value := m [keys [i ]].GetVal ()
110127
111128 valueBytes , valueTypeBytes , err := serializeValue (value , entityKeySerializationVersion )
112129 if err != nil {
113130 return valueBytes , err
114131 }
115132
133+ // Add value type info
116134 typeBuffer := make ([]byte , 4 )
117135 binary .LittleEndian .PutUint32 (typeBuffer , uint32 (valueTypeBytes ))
136+ bufferList [offset ] = typeBuffer
137+ offset ++
118138
139+ // Add length info
119140 lenBuffer := make ([]byte , 4 )
120141 binary .LittleEndian .PutUint32 (lenBuffer , uint32 (len (* valueBytes )))
142+ bufferList [offset ] = lenBuffer
143+ offset ++
121144
122- bufferList [offset + 0 ] = typeBuffer
123- bufferList [offset + 1 ] = lenBuffer
124- bufferList [offset + 2 ] = * valueBytes
145+ bufferList [offset ] = * valueBytes
146+ offset ++
125147 }
126148
127149 // Convert from an array of byte arrays to a single byte array
@@ -132,3 +154,26 @@ func serializeEntityKey(entityKey *types.EntityKey, entityKeySerializationVersio
132154
133155 return & entityKeyBuffer , nil
134156}
157+
158+ func serializeValue (value interface {}, entityKeySerializationVersion int64 ) (* []byte , types.ValueType_Enum , error ) {
159+ // TODO: Implement support for other types (at least the major types like ints, strings, bytes)
160+ switch x := (value ).(type ) {
161+ case * types.Value_StringVal :
162+ valueString := []byte (x .StringVal )
163+ return & valueString , types .ValueType_STRING , nil
164+ case * types.Value_BytesVal :
165+ return & x .BytesVal , types .ValueType_BYTES , nil
166+ case * types.Value_Int32Val :
167+ valueBuffer := make ([]byte , 4 )
168+ binary .LittleEndian .PutUint32 (valueBuffer , uint32 (x .Int32Val ))
169+ return & valueBuffer , types .ValueType_INT32 , nil
170+ case * types.Value_Int64Val :
171+ valueBuffer := make ([]byte , 8 )
172+ binary .LittleEndian .PutUint64 (valueBuffer , uint64 (x .Int64Val ))
173+ return & valueBuffer , types .ValueType_INT64 , nil
174+ case nil :
175+ return nil , types .ValueType_INVALID , fmt .Errorf ("could not detect type for %v" , x )
176+ default :
177+ return nil , types .ValueType_INVALID , fmt .Errorf ("could not detect type for %v" , x )
178+ }
179+ }
0 commit comments