@@ -87,41 +87,63 @@ func serializeEntityKey(entityKey *types.EntityKey, entityKeySerializationVersio
87
87
}
88
88
89
89
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
94
92
95
93
// Build the key
96
- length := 5 * len (keys )
94
+ length := 7 * len (keys )
97
95
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
+ }
98
106
99
107
for i := 0 ; i < len (keys ); i ++ {
100
- offset := i * 2
108
+ // Add the key type STRING info
101
109
byteBuffer := make ([]byte , 4 )
102
110
binary .LittleEndian .PutUint32 (byteBuffer , uint32 (types .ValueType_Enum_value ["STRING" ]))
103
111
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 ++
105
123
}
106
124
107
125
for i := 0 ; i < len (keys ); i ++ {
108
- offset := (2 * len (keys )) + (i * 3 )
109
126
value := m [keys [i ]].GetVal ()
110
127
111
128
valueBytes , valueTypeBytes , err := serializeValue (value , entityKeySerializationVersion )
112
129
if err != nil {
113
130
return valueBytes , err
114
131
}
115
132
133
+ // Add value type info
116
134
typeBuffer := make ([]byte , 4 )
117
135
binary .LittleEndian .PutUint32 (typeBuffer , uint32 (valueTypeBytes ))
136
+ bufferList [offset ] = typeBuffer
137
+ offset ++
118
138
139
+ // Add length info
119
140
lenBuffer := make ([]byte , 4 )
120
141
binary .LittleEndian .PutUint32 (lenBuffer , uint32 (len (* valueBytes )))
142
+ bufferList [offset ] = lenBuffer
143
+ offset ++
121
144
122
- bufferList [offset + 0 ] = typeBuffer
123
- bufferList [offset + 1 ] = lenBuffer
124
- bufferList [offset + 2 ] = * valueBytes
145
+ bufferList [offset ] = * valueBytes
146
+ offset ++
125
147
}
126
148
127
149
// Convert from an array of byte arrays to a single byte array
@@ -132,3 +154,26 @@ func serializeEntityKey(entityKey *types.EntityKey, entityKeySerializationVersio
132
154
133
155
return & entityKeyBuffer , nil
134
156
}
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