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

Side by Side Diff: service/datastore/properties.go

Issue 1363063002: Add ability to estimate the size of a PropertyMap (Closed) Base URL: https://github.com/luci/gae.git@minor_tweak
Patch Set: fix errcheck madness Created 5 years, 3 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/datastore/key.go ('k') | service/datastore/size_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 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
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
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 }
OLDNEW
« no previous file with comments | « service/datastore/key.go ('k') | service/datastore/size_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698