Index: service/datastore/properties.go |
diff --git a/service/datastore/properties.go b/service/datastore/properties.go |
index 9890a64c6aa3ce2ae7168f2f03e8b0447e10835b..051d8fbf146716b329709fc74ef12b0ec5dfd829 100644 |
--- a/service/datastore/properties.go |
+++ b/service/datastore/properties.go |
@@ -588,6 +588,33 @@ func (s PropertySlice) Len() int { return len(s) } |
func (s PropertySlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } |
func (s PropertySlice) Less(i, j int) bool { return s[i].Less(&s[j]) } |
+// EstimateSize estimates the amount of space that this Property would consume |
+// if it were committed as part of an entity in the real production datastore. |
+// |
+// It uses https://cloud.google.com/appengine/articles/storage_breakdown?csw=1 |
+// as a guide for these values. |
+func (p *Property) EstimateSize(withNamespace bool) int { |
+ switch p.Type() { |
+ case PTNull: |
+ return 1 |
+ case PTBool: |
+ return 1 + 4 |
+ case PTInt, PTTime, PTFloat: |
+ return 1 + 8 |
+ case PTGeoPoint: |
+ return 1 + (8 * 2) |
+ case PTString: |
+ return 1 + len(p.value.(string)) |
+ case PTBlobKey: |
+ return 1 + len(p.value.(blobstore.Key)) |
+ case PTBytes: |
+ return 1 + len(p.value.([]byte)) |
+ case PTKey: |
+ return 1 + p.value.(*Key).EstimateSize(withNamespace) |
+ } |
+ panic(fmt.Errorf("Unknown property type: %s", p.Type().String())) |
+} |
+ |
// MetaGetter is a subinterface of PropertyLoadSaver, but is also used to |
// abstract the meta argument for RawInterface.GetMulti. |
type MetaGetter interface { |
@@ -767,6 +794,25 @@ func (pm PropertyMap) Problem() error { |
return nil |
} |
+// EstimateSize estimates the size that it would take to encode this PropertyMap |
+// in the production Appengine datastore. The calculation excludes metadata |
+// fields in the map. |
+// |
+// It uses https://cloud.google.com/appengine/articles/storage_breakdown?csw=1 |
+// as a guide for sizes. |
+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
|
+ ret := 0 |
+ for k, vals := range pm { |
+ if !isMetaKey(k) { |
+ ret += len(k) |
+ for i := range vals { |
+ ret += vals[i].EstimateSize(withNamespace) |
+ } |
+ } |
+ } |
+ return ret |
+} |
+ |
func isMetaKey(k string) bool { |
// empty counts as a metakey since it's not a valid data key, but it's |
// not really a valid metakey either. |