Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(637)

Side by Side Diff: service/rawdatastore/serialize.go

Issue 1247283003: Improve docs (Closed) Base URL: https://github.com/luci/gae.git@reduce_size
Patch Set: fix comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « service/rawdatastore/properties.go ('k') | service/rawdatastore/serialize_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package rawdatastore 5 package rawdatastore
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 ret.IntID, _, err = cmpbin.ReadInt(buf) 144 ret.IntID, _, err = cmpbin.ReadInt(buf)
145 if err == nil && ret.IntID <= 0 { 145 if err == nil && ret.IntID <= 0 {
146 err = errors.New("helper: decoded key with empty stringI D and zero/negative intID") 146 err = errors.New("helper: decoded key with empty stringI D and zero/negative intID")
147 } 147 }
148 default: 148 default:
149 err = fmt.Errorf("helper: invalid type %s", PropertyType(typ)) 149 err = fmt.Errorf("helper: invalid type %s", PropertyType(typ))
150 } 150 }
151 return 151 return
152 } 152 }
153 153
154 // WriteGeoPoint writes a GeoPoint to the buffer. 154 // Write writes a GeoPoint to the buffer.
155 func WriteGeoPoint(buf Buffer, gp GeoPoint) (err error) { 155 func (gp GeoPoint) Write(buf Buffer) (err error) {
156 defer recoverTo(&err) 156 defer recoverTo(&err)
157 _, e := cmpbin.WriteFloat64(buf, gp.Lat) 157 _, e := cmpbin.WriteFloat64(buf, gp.Lat)
158 panicIf(e) 158 panicIf(e)
159 _, e = cmpbin.WriteFloat64(buf, gp.Lng) 159 _, e = cmpbin.WriteFloat64(buf, gp.Lng)
160 return e 160 return e
161 } 161 }
162 162
163 // ReadGeoPoint reads a GeoPoint from the buffer. 163 // Read reads a GeoPoint from the buffer.
164 func ReadGeoPoint(buf Buffer) (gp GeoPoint, err error) { 164 func (gp *GeoPoint) Read(buf Buffer) (err error) {
165 defer recoverTo(&err) 165 defer recoverTo(&err)
166 e := error(nil) 166 e := error(nil)
167 gp.Lat, _, e = cmpbin.ReadFloat64(buf) 167 gp.Lat, _, e = cmpbin.ReadFloat64(buf)
168 panicIf(e) 168 panicIf(e)
169 169
170 gp.Lng, _, e = cmpbin.ReadFloat64(buf) 170 gp.Lng, _, e = cmpbin.ReadFloat64(buf)
171 panicIf(e) 171 panicIf(e)
172 172
173 if !gp.Valid() { 173 if !gp.Valid() {
174 err = fmt.Errorf("helper: decoded invalid GeoPoint: %v", gp) 174 err = fmt.Errorf("helper: decoded invalid GeoPoint: %v", gp)
(...skipping 16 matching lines...) Expand all
191 191
192 // ReadTime reads a time.Time from the buffer. 192 // ReadTime reads a time.Time from the buffer.
193 func ReadTime(buf Buffer) (time.Time, error) { 193 func ReadTime(buf Buffer) (time.Time, error) {
194 v, _, err := cmpbin.ReadUint(buf) 194 v, _, err := cmpbin.ReadUint(buf)
195 if err != nil { 195 if err != nil {
196 return time.Time{}, err 196 return time.Time{}, err
197 } 197 }
198 return time.Unix(int64(v/1e6), int64((v%1e6)*1e3)).UTC(), nil 198 return time.Unix(int64(v/1e6), int64((v%1e6)*1e3)).UTC(), nil
199 } 199 }
200 200
201 // WriteProperty writes a Property to the buffer. `context` behaves the same 201 // Write writes a Property to the buffer. `context` behaves the same
202 // way that it does for WriteKey, but only has an effect if `p` contains a 202 // way that it does for WriteKey, but only has an effect if `p` contains a
203 // Key as its Value. 203 // Key as its Value.
204 func WriteProperty(buf Buffer, p Property, context KeyContext) (err error) { 204 func (p *Property) Write(buf Buffer, context KeyContext) (err error) {
205 defer recoverTo(&err) 205 defer recoverTo(&err)
206 typb := byte(p.Type()) 206 typb := byte(p.Type())
207 if p.IndexSetting() == NoIndex { 207 if p.IndexSetting() == NoIndex {
208 typb |= 0x80 208 typb |= 0x80
209 } 209 }
210 panicIf(buf.WriteByte(typb)) 210 panicIf(buf.WriteByte(typb))
211 switch p.Type() { 211 switch p.Type() {
212 case PTNull, PTBoolTrue, PTBoolFalse: 212 case PTNull, PTBoolTrue, PTBoolFalse:
213 case PTInt: 213 case PTInt:
214 _, err = cmpbin.WriteInt(buf, p.Value().(int64)) 214 _, err = cmpbin.WriteInt(buf, p.Value().(int64))
215 case PTFloat: 215 case PTFloat:
216 _, err = cmpbin.WriteFloat64(buf, p.Value().(float64)) 216 _, err = cmpbin.WriteFloat64(buf, p.Value().(float64))
217 case PTString: 217 case PTString:
218 _, err = cmpbin.WriteString(buf, p.Value().(string)) 218 _, err = cmpbin.WriteString(buf, p.Value().(string))
219 case PTBytes: 219 case PTBytes:
220 if p.IndexSetting() == NoIndex { 220 if p.IndexSetting() == NoIndex {
221 _, err = cmpbin.WriteBytes(buf, p.Value().([]byte)) 221 _, err = cmpbin.WriteBytes(buf, p.Value().([]byte))
222 } else { 222 } else {
223 _, err = cmpbin.WriteBytes(buf, p.Value().(ByteString)) 223 _, err = cmpbin.WriteBytes(buf, p.Value().(ByteString))
224 } 224 }
225 case PTTime: 225 case PTTime:
226 err = WriteTime(buf, p.Value().(time.Time)) 226 err = WriteTime(buf, p.Value().(time.Time))
227 case PTGeoPoint: 227 case PTGeoPoint:
228 » » err = WriteGeoPoint(buf, p.Value().(GeoPoint)) 228 » » err = p.Value().(GeoPoint).Write(buf)
229 case PTKey: 229 case PTKey:
230 err = WriteKey(buf, context, p.Value().(Key)) 230 err = WriteKey(buf, context, p.Value().(Key))
231 case PTBlobKey: 231 case PTBlobKey:
232 _, err = cmpbin.WriteString(buf, string(p.Value().(blobstore.Key ))) 232 _, err = cmpbin.WriteString(buf, string(p.Value().(blobstore.Key )))
233 } 233 }
234 return 234 return
235 } 235 }
236 236
237 // ReadProperty reads a Property from the buffer. `context`, `appid`, and 237 // Read reads a Property from the buffer. `context`, `appid`, and
238 // `namespace` behave the same way they do for ReadKey, but only have an 238 // `namespace` behave the same way they do for ReadKey, but only have an
239 // effect if the decoded property has a Key value. 239 // effect if the decoded property has a Key value.
240 func ReadProperty(buf Buffer, context KeyContext, appid, namespace string) (p Pr operty, err error) { 240 func (p *Property) Read(buf Buffer, context KeyContext, appid, namespace string) (err error) {
241 val := interface{}(nil) 241 val := interface{}(nil)
242 typb, err := buf.ReadByte() 242 typb, err := buf.ReadByte()
243 if err != nil { 243 if err != nil {
244 return 244 return
245 } 245 }
246 is := ShouldIndex 246 is := ShouldIndex
247 if (typb & 0x80) != 0 { 247 if (typb & 0x80) != 0 {
248 is = NoIndex 248 is = NoIndex
249 } 249 }
250 switch PropertyType(typb & 0x7f) { 250 switch PropertyType(typb & 0x7f) {
(...skipping 14 matching lines...) Expand all
265 break 265 break
266 } 266 }
267 if is == NoIndex { 267 if is == NoIndex {
268 val = b 268 val = b
269 } else { 269 } else {
270 val = ByteString(b) 270 val = ByteString(b)
271 } 271 }
272 case PTTime: 272 case PTTime:
273 val, err = ReadTime(buf) 273 val, err = ReadTime(buf)
274 case PTGeoPoint: 274 case PTGeoPoint:
275 » » val, err = ReadGeoPoint(buf) 275 » » gp := GeoPoint{}
276 » » err = gp.Read(buf)
277 » » val = gp
276 case PTKey: 278 case PTKey:
277 val, err = ReadKey(buf, context, appid, namespace) 279 val, err = ReadKey(buf, context, appid, namespace)
278 case PTBlobKey: 280 case PTBlobKey:
279 s := "" 281 s := ""
280 if s, _, err = cmpbin.ReadString(buf); err != nil { 282 if s, _, err = cmpbin.ReadString(buf); err != nil {
281 break 283 break
282 } 284 }
283 val = blobstore.Key(s) 285 val = blobstore.Key(s)
284 default: 286 default:
285 err = fmt.Errorf("read: unknown type! %v", typb) 287 err = fmt.Errorf("read: unknown type! %v", typb)
286 } 288 }
287 if err == nil { 289 if err == nil {
288 err = p.SetValue(val, is) 290 err = p.SetValue(val, is)
289 } 291 }
290 return 292 return
291 } 293 }
292 294
293 // WritePropertyMap writes an entire PropertyMap to the buffer. `context` 295 // Write writes an entire PropertyMap to the buffer. `context`
294 // behaves the same way that it does for WriteKey. If 296 // behaves the same way that it does for WriteKey. If
295 // WritePropertyMapDeterministic is true, then the rows will be sorted by 297 // WritePropertyMapDeterministic is true, then the rows will be sorted by
296 // property name before they're serialized to buf (mostly useful for testing, 298 // property name before they're serialized to buf (mostly useful for testing,
297 // but also potentially useful if you need to make a hash of the property data). 299 // but also potentially useful if you need to make a hash of the property data).
298 func WritePropertyMap(buf Buffer, propMap PropertyMap, context KeyContext) (err error) { 300 func (pm PropertyMap) Write(buf Buffer, context KeyContext) (err error) {
299 defer recoverTo(&err) 301 defer recoverTo(&err)
300 » rows := make(sort.StringSlice, 0, len(propMap)) 302 » rows := make(sort.StringSlice, 0, len(pm))
301 tmpBuf := &bytes.Buffer{} 303 tmpBuf := &bytes.Buffer{}
302 » for name, vals := range propMap { 304 » for name, vals := range pm {
303 tmpBuf.Reset() 305 tmpBuf.Reset()
304 _, e := cmpbin.WriteString(tmpBuf, name) 306 _, e := cmpbin.WriteString(tmpBuf, name)
305 panicIf(e) 307 panicIf(e)
306 _, e = cmpbin.WriteUint(tmpBuf, uint64(len(vals))) 308 _, e = cmpbin.WriteUint(tmpBuf, uint64(len(vals)))
307 panicIf(e) 309 panicIf(e)
308 for _, p := range vals { 310 for _, p := range vals {
309 » » » panicIf(WriteProperty(tmpBuf, p, context)) 311 » » » panicIf(p.Write(tmpBuf, context))
310 } 312 }
311 rows = append(rows, tmpBuf.String()) 313 rows = append(rows, tmpBuf.String())
312 } 314 }
313 315
314 if WritePropertyMapDeterministic { 316 if WritePropertyMapDeterministic {
315 rows.Sort() 317 rows.Sort()
316 } 318 }
317 319
318 » _, e := cmpbin.WriteUint(buf, uint64(len(propMap))) 320 » _, e := cmpbin.WriteUint(buf, uint64(len(pm)))
319 panicIf(e) 321 panicIf(e)
320 for _, r := range rows { 322 for _, r := range rows {
321 _, e := buf.WriteString(r) 323 _, e := buf.WriteString(r)
322 panicIf(e) 324 panicIf(e)
323 } 325 }
324 return 326 return
325 } 327 }
326 328
327 // ReadPropertyMap reads a PropertyMap from the buffer. `context` and 329 // Read reads a PropertyMap from the buffer. `context` and
328 // friends behave the same way that they do for ReadKey. 330 // friends behave the same way that they do for ReadKey.
329 func ReadPropertyMap(buf Buffer, context KeyContext, appid, namespace string) (p ropMap PropertyMap, err error) { 331 func (pm PropertyMap) Read(buf Buffer, context KeyContext, appid, namespace stri ng) (err error) {
330 defer recoverTo(&err) 332 defer recoverTo(&err)
331 333
332 numRows := uint64(0) 334 numRows := uint64(0)
333 numRows, _, e := cmpbin.ReadUint(buf) 335 numRows, _, e := cmpbin.ReadUint(buf)
334 panicIf(e) 336 panicIf(e)
335 if numRows > ReadPropertyMapReasonableLimit { 337 if numRows > ReadPropertyMapReasonableLimit {
336 err = fmt.Errorf("helper: tried to decode map with huge number o f rows %d", numRows) 338 err = fmt.Errorf("helper: tried to decode map with huge number o f rows %d", numRows)
337 return 339 return
338 } 340 }
339 341
340 name, prop := "", Property{} 342 name, prop := "", Property{}
341 propMap = make(PropertyMap, numRows)
342 for i := uint64(0); i < numRows; i++ { 343 for i := uint64(0); i < numRows; i++ {
343 name, _, e = cmpbin.ReadString(buf) 344 name, _, e = cmpbin.ReadString(buf)
344 panicIf(e) 345 panicIf(e)
345 346
346 numProps, _, e := cmpbin.ReadUint(buf) 347 numProps, _, e := cmpbin.ReadUint(buf)
347 panicIf(e) 348 panicIf(e)
348 if numProps > ReadPropertyMapReasonableLimit { 349 if numProps > ReadPropertyMapReasonableLimit {
349 err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps) 350 err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps)
350 return 351 return
351 } 352 }
352 props := make([]Property, 0, numProps) 353 props := make([]Property, 0, numProps)
353 for j := uint64(0); j < numProps; j++ { 354 for j := uint64(0); j < numProps; j++ {
354 » » » prop, e = ReadProperty(buf, context, appid, namespace) 355 » » » panicIf(prop.Read(buf, context, appid, namespace))
355 » » » panicIf(e)
356 props = append(props, prop) 356 props = append(props, prop)
357 } 357 }
358 » » propMap[name] = props 358 » » pm[name] = props
359 } 359 }
360 return 360 return
361 } 361 }
362 362
363 type parseError error 363 type parseError error
364 364
365 func panicIf(err error) { 365 func panicIf(err error) {
366 if err != nil { 366 if err != nil {
367 panic(parseError(err)) 367 panic(parseError(err))
368 } 368 }
369 } 369 }
370 370
371 func recoverTo(err *error) { 371 func recoverTo(err *error) {
372 if r := recover(); r != nil { 372 if r := recover(); r != nil {
373 if rerr := r.(parseError); rerr != nil { 373 if rerr := r.(parseError); rerr != nil {
374 *err = error(rerr) 374 *err = error(rerr)
375 } 375 }
376 } 376 }
377 } 377 }
OLDNEW
« no previous file with comments | « service/rawdatastore/properties.go ('k') | service/rawdatastore/serialize_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698