OLD | NEW |
---|---|
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 datastore | 5 package datastore |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
11 "sort" | 11 "sort" |
12 "time" | 12 "time" |
13 | 13 |
14 "github.com/luci/gae/service/blobstore" | 14 "github.com/luci/gae/service/blobstore" |
15 "github.com/luci/luci-go/common/cmpbin" | 15 "github.com/luci/luci-go/common/cmpbin" |
16 ) | 16 ) |
17 | 17 |
18 const MaxIndexColumns = 64 | |
dnj (Google)
2015/08/14 22:53:54
Can you document why 64?
iannucci
2015/08/15 01:59:25
done
| |
19 | |
18 // WritePropertyMapDeterministic allows tests to make WritePropertyMap | 20 // WritePropertyMapDeterministic allows tests to make WritePropertyMap |
19 // deterministic. | 21 // deterministic. |
20 var WritePropertyMapDeterministic = false | 22 var WritePropertyMapDeterministic = false |
21 | 23 |
22 // ReadPropertyMapReasonableLimit sets a limit on the number of rows and | 24 // ReadPropertyMapReasonableLimit sets a limit on the number of rows and |
23 // number of properties per row which can be read by ReadPropertyMap. The | 25 // number of properties per row which can be read by ReadPropertyMap. The |
24 // total number of Property objects readable by this method is this number | 26 // total number of Property objects readable by this method is this number |
25 // squared (e.g. Limit rows * Limit properties) | 27 // squared (e.g. Limit rows * Limit properties) |
26 const ReadPropertyMapReasonableLimit uint64 = 30000 | 28 const ReadPropertyMapReasonableLimit uint64 = 30000 |
27 | 29 |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 props := make([]Property, 0, numProps) | 360 props := make([]Property, 0, numProps) |
359 for j := uint64(0); j < numProps; j++ { | 361 for j := uint64(0); j < numProps; j++ { |
360 panicIf(prop.Read(buf, context, appid, namespace)) | 362 panicIf(prop.Read(buf, context, appid, namespace)) |
361 props = append(props, prop) | 363 props = append(props, prop) |
362 } | 364 } |
363 pm[name] = props | 365 pm[name] = props |
364 } | 366 } |
365 return | 367 return |
366 } | 368 } |
367 | 369 |
370 func (c *IndexColumn) Write(buf Buffer) (err error) { | |
371 defer recoverTo(&err) | |
372 | |
373 if c.Direction == ASCENDING { | |
374 panicIf(buf.WriteByte(0)) | |
375 } else { | |
376 panicIf(buf.WriteByte(1)) | |
377 } | |
378 _, err = cmpbin.WriteString(buf, c.Property) | |
379 return | |
380 } | |
381 | |
382 func (c *IndexColumn) Read(buf Buffer) (err error) { | |
383 defer recoverTo(&err) | |
384 | |
385 dir, err := buf.ReadByte() | |
386 panicIf(err) | |
387 | |
388 c.Direction = dir != 0 | |
dnj (Google)
2015/08/14 22:53:54
Since you use constants (ASCENDING) for writing, y
iannucci
2015/08/15 01:59:25
Done.
| |
389 c.Property, _, err = cmpbin.ReadString(buf) | |
390 return err | |
391 } | |
392 | |
393 func (i *IndexDefinition) Write(buf Buffer) (err error) { | |
394 defer recoverTo(&err) | |
395 | |
396 if i.Builtin() { | |
397 panicIf(buf.WriteByte(0)) | |
398 } else { | |
399 panicIf(buf.WriteByte(1)) | |
400 } | |
401 _, err = cmpbin.WriteString(buf, i.Kind) | |
402 panicIf(err) | |
403 if !i.Ancestor { | |
404 panicIf(buf.WriteByte(0)) | |
405 } else { | |
406 panicIf(buf.WriteByte(1)) | |
407 } | |
408 _, err = cmpbin.WriteUint(buf, uint64(len(i.SortBy))) | |
409 panicIf(err) | |
410 for _, sb := range i.SortBy { | |
411 panicIf(sb.Write(buf)) | |
412 } | |
413 return | |
414 } | |
415 | |
416 func (i *IndexDefinition) Read(buf Buffer) (err error) { | |
417 defer recoverTo(&err) | |
418 | |
419 // discard builtin/complex byte | |
420 _, err = buf.ReadByte() | |
421 panicIf(err) | |
422 | |
423 i.Kind, _, err = cmpbin.ReadString(buf) | |
424 panicIf(err) | |
425 | |
426 anc, err := buf.ReadByte() | |
427 panicIf(err) | |
428 | |
429 i.Ancestor = anc == 1 | |
430 | |
431 numSorts, _, err := cmpbin.ReadUint(buf) | |
432 panicIf(err) | |
433 | |
434 if numSorts > MaxIndexColumns { | |
435 return fmt.Errorf("datastore: Got over %d sort orders: %d", | |
436 MaxIndexColumns, numSorts) | |
437 } | |
438 | |
439 if numSorts > 0 { | |
440 i.SortBy = make([]IndexColumn, numSorts) | |
441 for idx := range i.SortBy { | |
442 panicIf(i.SortBy[idx].Read(buf)) | |
443 } | |
444 } | |
445 | |
446 return | |
447 } | |
448 | |
368 type parseError error | 449 type parseError error |
369 | 450 |
370 func panicIf(err error) { | 451 func panicIf(err error) { |
371 if err != nil { | 452 if err != nil { |
372 panic(parseError(err)) | 453 panic(parseError(err)) |
373 } | 454 } |
374 } | 455 } |
375 | 456 |
376 func recoverTo(err *error) { | 457 func recoverTo(err *error) { |
377 if r := recover(); r != nil { | 458 if r := recover(); r != nil { |
378 if rerr := r.(parseError); rerr != nil { | 459 if rerr := r.(parseError); rerr != nil { |
379 *err = error(rerr) | 460 *err = error(rerr) |
380 } | 461 } |
381 } | 462 } |
382 } | 463 } |
OLD | NEW |