Chromium Code Reviews| 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 |