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 "encoding/base64" | 8 "encoding/base64" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 panic(fmt.Errorf("bad type: %s", p.propType)) | 581 panic(fmt.Errorf("bad type: %s", p.propType)) |
582 } | 582 } |
583 | 583 |
584 // PropertySlice is a slice of Properties. It implements sort.Interface. | 584 // PropertySlice is a slice of Properties. It implements sort.Interface. |
585 type PropertySlice []Property | 585 type PropertySlice []Property |
586 | 586 |
587 func (s PropertySlice) Len() int { return len(s) } | 587 func (s PropertySlice) Len() int { return len(s) } |
588 func (s PropertySlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } | 588 func (s PropertySlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } |
589 func (s PropertySlice) Less(i, j int) bool { return s[i].Less(&s[j]) } | 589 func (s PropertySlice) Less(i, j int) bool { return s[i].Less(&s[j]) } |
590 | 590 |
| 591 // EstimateSize estimates the amount of space that this Property would consume |
| 592 // if it were committed as part of an entity in the real production datastore. |
| 593 // |
| 594 // It uses https://cloud.google.com/appengine/articles/storage_breakdown?csw=1 |
| 595 // as a guide for these values. |
| 596 func (p *Property) EstimateSize() int64 { |
| 597 switch p.Type() { |
| 598 case PTNull: |
| 599 return 1 |
| 600 case PTBool: |
| 601 return 1 + 4 |
| 602 case PTInt, PTTime, PTFloat: |
| 603 return 1 + 8 |
| 604 case PTGeoPoint: |
| 605 return 1 + (8 * 2) |
| 606 case PTString: |
| 607 return 1 + int64(len(p.value.(string))) |
| 608 case PTBlobKey: |
| 609 return 1 + int64(len(p.value.(blobstore.Key))) |
| 610 case PTBytes: |
| 611 return 1 + int64(len(p.value.([]byte))) |
| 612 case PTKey: |
| 613 return 1 + p.value.(*Key).EstimateSize() |
| 614 } |
| 615 panic(fmt.Errorf("Unknown property type: %s", p.Type().String())) |
| 616 } |
| 617 |
591 // MetaGetter is a subinterface of PropertyLoadSaver, but is also used to | 618 // MetaGetter is a subinterface of PropertyLoadSaver, but is also used to |
592 // abstract the meta argument for RawInterface.GetMulti. | 619 // abstract the meta argument for RawInterface.GetMulti. |
593 type MetaGetter interface { | 620 type MetaGetter interface { |
594 // GetMeta will get information about the field which has the struct tag
in | 621 // GetMeta will get information about the field which has the struct tag
in |
595 // the form of `gae:"$<key>[,<default>]?"`. | 622 // the form of `gae:"$<key>[,<default>]?"`. |
596 // | 623 // |
597 // Supported metadata types are: | 624 // Supported metadata types are: |
598 // int64 - may have default (ascii encoded base-10) | 625 // int64 - may have default (ascii encoded base-10) |
599 // string - may have default | 626 // string - may have default |
600 // Toggle - MUST have default ("true" or "false") | 627 // Toggle - MUST have default ("true" or "false") |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 } | 787 } |
761 pm["$"+key] = []Property{prop} | 788 pm["$"+key] = []Property{prop} |
762 return nil | 789 return nil |
763 } | 790 } |
764 | 791 |
765 // Problem implements PropertyLoadSaver.Problem. It ALWAYS returns nil. | 792 // Problem implements PropertyLoadSaver.Problem. It ALWAYS returns nil. |
766 func (pm PropertyMap) Problem() error { | 793 func (pm PropertyMap) Problem() error { |
767 return nil | 794 return nil |
768 } | 795 } |
769 | 796 |
| 797 // EstimateSize estimates the size that it would take to encode this PropertyMap |
| 798 // in the production Appengine datastore. The calculation excludes metadata |
| 799 // fields in the map. |
| 800 // |
| 801 // It uses https://cloud.google.com/appengine/articles/storage_breakdown?csw=1 |
| 802 // as a guide for sizes. |
| 803 func (pm PropertyMap) EstimateSize() int64 { |
| 804 ret := int64(0) |
| 805 for k, vals := range pm { |
| 806 if !isMetaKey(k) { |
| 807 ret += int64(len(k)) |
| 808 for i := range vals { |
| 809 ret += vals[i].EstimateSize() |
| 810 } |
| 811 } |
| 812 } |
| 813 return ret |
| 814 } |
| 815 |
770 func isMetaKey(k string) bool { | 816 func isMetaKey(k string) bool { |
771 // empty counts as a metakey since it's not a valid data key, but it's | 817 // empty counts as a metakey since it's not a valid data key, but it's |
772 // not really a valid metakey either. | 818 // not really a valid metakey either. |
773 return k == "" || k[0] == '$' | 819 return k == "" || k[0] == '$' |
774 } | 820 } |
775 | 821 |
776 // GetMetaDefaultImpl is the implementation of PropertyLoadSaver.GetMetaDefault. | 822 // GetMetaDefaultImpl is the implementation of PropertyLoadSaver.GetMetaDefault. |
777 // | 823 // |
778 // It takes the normal GetMeta function, the key and the default, and returns | 824 // It takes the normal GetMeta function, the key and the default, and returns |
779 // the value according to PropertyLoadSaver.GetMetaDefault. | 825 // the value according to PropertyLoadSaver.GetMetaDefault. |
780 func GetMetaDefaultImpl(gm func(string) (interface{}, error), key string, dflt i
nterface{}) interface{} { | 826 func GetMetaDefaultImpl(gm func(string) (interface{}, error), key string, dflt i
nterface{}) interface{} { |
781 dflt = UpconvertUnderlyingType(dflt) | 827 dflt = UpconvertUnderlyingType(dflt) |
782 cur, err := gm(key) | 828 cur, err := gm(key) |
783 if err != nil { | 829 if err != nil { |
784 return dflt | 830 return dflt |
785 } | 831 } |
786 if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) { | 832 if dflt != nil && reflect.TypeOf(cur) != reflect.TypeOf(dflt) { |
787 return dflt | 833 return dflt |
788 } | 834 } |
789 return cur | 835 return cur |
790 } | 836 } |
OLD | NEW |