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

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

Issue 1358743002: Make Get operations only serialize the bare minimum. (Closed) Base URL: https://github.com/luci/gae.git@fix_time
Patch Set: PropertyMap should always copy on save-out functions to avoid external mutation 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/datastore_test.go ('k') | service/datastore/pls_impl.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 "fmt" 8 "fmt"
9 "reflect" 9 "reflect"
10 10
11 "github.com/luci/luci-go/common/errors" 11 "github.com/luci/luci-go/common/errors"
12 ) 12 )
13 13
14 type multiArgType struct { 14 type multiArgType struct {
15 valid bool 15 valid bool
16 16
17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error) 17 » getKey func(aid, ns string, slot reflect.Value) (*Key, error)
18 » getPM func(slot reflect.Value) (PropertyMap, error) 18 » getPM func(slot reflect.Value) (PropertyMap, error)
19 » setPM func(slot reflect.Value, pm PropertyMap) error 19 » getMetaPM func(slot reflect.Value) PropertyMap
20 » setKey func(slot reflect.Value, k *Key) 20 » setPM func(slot reflect.Value, pm PropertyMap) error
21 » newElem func() reflect.Value 21 » setKey func(slot reflect.Value, k *Key)
22 » newElem func() reflect.Value
22 } 23 }
23 24
24 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value) ([]*Key , []PropertyMap, error) { 25 func (mat *multiArgType) GetKeysPMs(aid, ns string, slice reflect.Value, meta bo ol) ([]*Key, []PropertyMap, error) {
25 retKey := make([]*Key, slice.Len()) 26 retKey := make([]*Key, slice.Len())
26 retPM := make([]PropertyMap, slice.Len()) 27 retPM := make([]PropertyMap, slice.Len())
28 getter := mat.getPM
29 if meta {
30 getter = func(slot reflect.Value) (PropertyMap, error) {
31 return mat.getMetaPM(slot), nil
32 }
33 }
27 lme := errors.NewLazyMultiError(len(retKey)) 34 lme := errors.NewLazyMultiError(len(retKey))
28 for i := range retKey { 35 for i := range retKey {
29 key, err := mat.getKey(aid, ns, slice.Index(i)) 36 key, err := mat.getKey(aid, ns, slice.Index(i))
30 if !lme.Assign(i, err) { 37 if !lme.Assign(i, err) {
31 retKey[i] = key 38 retKey[i] = key
32 » » » pm, err := mat.getPM(slice.Index(i)) 39 » » » pm, err := getter(slice.Index(i))
33 if !lme.Assign(i, err) { 40 if !lme.Assign(i, err) {
34 retPM[i] = pm 41 retPM[i] = pm
35 } 42 }
36 } 43 }
37 } 44 }
38 return retKey, retPM, lme.Get() 45 return retKey, retPM, lme.Get()
39 } 46 }
40 47
41 // parseMultiArg checks that v has type []S, []*S, []I, []P or []*P, for some 48 // parseMultiArg checks that v has type []S, []*S, []I, []P or []*P, for some
42 // struct type S, for some interface type I, or some non-interface non-pointer 49 // struct type S, for some interface type I, or some non-interface non-pointer
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 func multiArgTypePLS(et reflect.Type) multiArgType { 90 func multiArgTypePLS(et reflect.Type) multiArgType {
84 ret := multiArgType{ 91 ret := multiArgType{
85 valid: true, 92 valid: true,
86 93
87 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { 94 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
88 return newKeyObjErr(aid, ns, slot.Addr().Interface()) 95 return newKeyObjErr(aid, ns, slot.Addr().Interface())
89 }, 96 },
90 getPM: func(slot reflect.Value) (PropertyMap, error) { 97 getPM: func(slot reflect.Value) (PropertyMap, error) {
91 return slot.Addr().Interface().(PropertyLoadSaver).Save( true) 98 return slot.Addr().Interface().(PropertyLoadSaver).Save( true)
92 }, 99 },
100 getMetaPM: func(slot reflect.Value) PropertyMap {
101 return slot.Addr().Interface().(PropertyLoadSaver).GetAl lMeta()
102 },
93 setPM: func(slot reflect.Value, pm PropertyMap) error { 103 setPM: func(slot reflect.Value, pm PropertyMap) error {
94 return slot.Addr().Interface().(PropertyLoadSaver).Load( pm) 104 return slot.Addr().Interface().(PropertyLoadSaver).Load( pm)
95 }, 105 },
96 setKey: func(slot reflect.Value, k *Key) { 106 setKey: func(slot reflect.Value, k *Key) {
97 setKey(slot.Addr().Interface(), k) 107 setKey(slot.Addr().Interface(), k)
98 }, 108 },
99 } 109 }
100 if et.Kind() == reflect.Map { 110 if et.Kind() == reflect.Map {
101 ret.newElem = func() reflect.Value { 111 ret.newElem = func() reflect.Value {
102 // Create a *map so that way slot.Addr() works above whe n this is 112 // Create a *map so that way slot.Addr() works above whe n this is
(...skipping 16 matching lines...) Expand all
119 func multiArgTypePLSPtr(et reflect.Type) multiArgType { 129 func multiArgTypePLSPtr(et reflect.Type) multiArgType {
120 ret := multiArgType{ 130 ret := multiArgType{
121 valid: true, 131 valid: true,
122 132
123 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { 133 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
124 return newKeyObjErr(aid, ns, slot.Interface()) 134 return newKeyObjErr(aid, ns, slot.Interface())
125 }, 135 },
126 getPM: func(slot reflect.Value) (PropertyMap, error) { 136 getPM: func(slot reflect.Value) (PropertyMap, error) {
127 return slot.Interface().(PropertyLoadSaver).Save(true) 137 return slot.Interface().(PropertyLoadSaver).Save(true)
128 }, 138 },
139 getMetaPM: func(slot reflect.Value) PropertyMap {
140 return slot.Interface().(PropertyLoadSaver).GetAllMeta()
141 },
129 setPM: func(slot reflect.Value, pm PropertyMap) error { 142 setPM: func(slot reflect.Value, pm PropertyMap) error {
130 return slot.Interface().(PropertyLoadSaver).Load(pm) 143 return slot.Interface().(PropertyLoadSaver).Load(pm)
131 }, 144 },
132 setKey: func(slot reflect.Value, k *Key) { 145 setKey: func(slot reflect.Value, k *Key) {
133 setKey(slot.Interface(), k) 146 setKey(slot.Interface(), k)
134 }, 147 },
135 } 148 }
136 if et.Kind() == reflect.Map { 149 if et.Kind() == reflect.Map {
137 ret.newElem = func() reflect.Value { 150 ret.newElem = func() reflect.Value {
138 ptr := reflect.New(et) 151 ptr := reflect.New(et)
(...skipping 17 matching lines...) Expand all
156 } 169 }
157 return multiArgType{ 170 return multiArgType{
158 valid: true, 171 valid: true,
159 172
160 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { 173 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
161 return newKeyObjErr(aid, ns, toPLS(slot)) 174 return newKeyObjErr(aid, ns, toPLS(slot))
162 }, 175 },
163 getPM: func(slot reflect.Value) (PropertyMap, error) { 176 getPM: func(slot reflect.Value) (PropertyMap, error) {
164 return toPLS(slot).(PropertyLoadSaver).Save(true) 177 return toPLS(slot).(PropertyLoadSaver).Save(true)
165 }, 178 },
179 getMetaPM: func(slot reflect.Value) PropertyMap {
180 return toPLS(slot).(PropertyLoadSaver).GetAllMeta()
181 },
166 setPM: func(slot reflect.Value, pm PropertyMap) error { 182 setPM: func(slot reflect.Value, pm PropertyMap) error {
167 return toPLS(slot).(PropertyLoadSaver).Load(pm) 183 return toPLS(slot).(PropertyLoadSaver).Load(pm)
168 }, 184 },
169 setKey: func(slot reflect.Value, k *Key) { 185 setKey: func(slot reflect.Value, k *Key) {
170 setKey(toPLS(slot), k) 186 setKey(toPLS(slot), k)
171 }, 187 },
172 newElem: func() reflect.Value { 188 newElem: func() reflect.Value {
173 return reflect.New(et).Elem() 189 return reflect.New(et).Elem()
174 }, 190 },
175 } 191 }
(...skipping 10 matching lines...) Expand all
186 } 202 }
187 return multiArgType{ 203 return multiArgType{
188 valid: true, 204 valid: true,
189 205
190 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { 206 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
191 return newKeyObjErr(aid, ns, toPLS(slot)) 207 return newKeyObjErr(aid, ns, toPLS(slot))
192 }, 208 },
193 getPM: func(slot reflect.Value) (PropertyMap, error) { 209 getPM: func(slot reflect.Value) (PropertyMap, error) {
194 return toPLS(slot).(PropertyLoadSaver).Save(true) 210 return toPLS(slot).(PropertyLoadSaver).Save(true)
195 }, 211 },
212 getMetaPM: func(slot reflect.Value) PropertyMap {
213 return toPLS(slot).(PropertyLoadSaver).GetAllMeta()
214 },
196 setPM: func(slot reflect.Value, pm PropertyMap) error { 215 setPM: func(slot reflect.Value, pm PropertyMap) error {
197 return toPLS(slot).(PropertyLoadSaver).Load(pm) 216 return toPLS(slot).(PropertyLoadSaver).Load(pm)
198 }, 217 },
199 setKey: func(slot reflect.Value, k *Key) { 218 setKey: func(slot reflect.Value, k *Key) {
200 setKey(toPLS(slot), k) 219 setKey(toPLS(slot), k)
201 }, 220 },
202 newElem: func() reflect.Value { 221 newElem: func() reflect.Value {
203 return reflect.New(et) 222 return reflect.New(et)
204 }, 223 },
205 } 224 }
206 } 225 }
207 226
208 // multiArgTypeInterface == []I 227 // multiArgTypeInterface == []I
209 func multiArgTypeInterface() multiArgType { 228 func multiArgTypeInterface() multiArgType {
210 return multiArgType{ 229 return multiArgType{
211 valid: true, 230 valid: true,
212 231
213 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) { 232 getKey: func(aid, ns string, slot reflect.Value) (*Key, error) {
214 return newKeyObjErr(aid, ns, slot.Elem().Interface()) 233 return newKeyObjErr(aid, ns, slot.Elem().Interface())
215 }, 234 },
216 getPM: func(slot reflect.Value) (PropertyMap, error) { 235 getPM: func(slot reflect.Value) (PropertyMap, error) {
217 pls := mkPLS(slot.Elem().Interface()) 236 pls := mkPLS(slot.Elem().Interface())
218 return pls.Save(true) 237 return pls.Save(true)
219 }, 238 },
239 getMetaPM: func(slot reflect.Value) PropertyMap {
240 pls := mkPLS(slot.Elem().Interface())
241 return pls.GetAllMeta()
242 },
220 setPM: func(slot reflect.Value, pm PropertyMap) error { 243 setPM: func(slot reflect.Value, pm PropertyMap) error {
221 pls := mkPLS(slot.Elem().Interface()) 244 pls := mkPLS(slot.Elem().Interface())
222 return pls.Load(pm) 245 return pls.Load(pm)
223 }, 246 },
224 setKey: func(slot reflect.Value, k *Key) { 247 setKey: func(slot reflect.Value, k *Key) {
225 setKey(slot.Elem().Interface(), k) 248 setKey(slot.Elem().Interface(), k)
226 }, 249 },
227 } 250 }
228 } 251 }
229 252
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 _ = pls.SetMeta("parent", key.Parent()) 285 _ = pls.SetMeta("parent", key.Parent())
263 } 286 }
264 } 287 }
265 288
266 func mkPLS(o interface{}) PropertyLoadSaver { 289 func mkPLS(o interface{}) PropertyLoadSaver {
267 if pls, ok := o.(PropertyLoadSaver); ok { 290 if pls, ok := o.(PropertyLoadSaver); ok {
268 return pls 291 return pls
269 } 292 }
270 return GetPLS(o) 293 return GetPLS(o)
271 } 294 }
OLDNEW
« no previous file with comments | « service/datastore/datastore_test.go ('k') | service/datastore/pls_impl.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698