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(withNamespace bool) int { | |
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 + len(p.value.(string)) | |
608 case PTBlobKey: | |
609 return 1 + len(p.value.(blobstore.Key)) | |
610 case PTBytes: | |
611 return 1 + len(p.value.([]byte)) | |
612 case PTKey: | |
613 return 1 + p.value.(*Key).EstimateSize(withNamespace) | |
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(withNamespace bool) int { | |
dnj (Google)
2015/09/23 20:03:19
Accumulating int, maybe should use int64?
dnj (Google)
2015/09/23 20:03:19
Why is "withNamespace" not always "true"?
iannucci
2015/09/23 20:28:41
good question. I looked at the doc and it seems li
| |
804 ret := 0 | |
805 for k, vals := range pm { | |
806 if !isMetaKey(k) { | |
807 ret += len(k) | |
808 for i := range vals { | |
809 ret += vals[i].EstimateSize(withNamespace) | |
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 |