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

Side by Side Diff: filter/dscache/support.go

Issue 1355783002: Refactor keys and queries in datastore service and implementation. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: appease errcheck 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 | « filter/dscache/plan.go ('k') | filter/featureBreaker/rds.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 dscache 5 package dscache
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "math/rand" 9 "math/rand"
10 "time" 10 "time"
11 11
12 ds "github.com/luci/gae/service/datastore" 12 ds "github.com/luci/gae/service/datastore"
13 "github.com/luci/gae/service/memcache" 13 "github.com/luci/gae/service/memcache"
14 log "github.com/luci/luci-go/common/logging" 14 log "github.com/luci/luci-go/common/logging"
15 "golang.org/x/net/context" 15 "golang.org/x/net/context"
16 ) 16 )
17 17
18 type supportContext struct { 18 type supportContext struct {
19 aid string 19 aid string
20 ns string 20 ns string
21 21
22 c context.Context 22 c context.Context
23 mc memcache.Interface 23 mc memcache.Interface
24 mr *rand.Rand 24 mr *rand.Rand
25 » shardsForKey func(ds.Key) int 25 » shardsForKey func(*ds.Key) int
26 } 26 }
27 27
28 func (s *supportContext) numShards(k ds.Key) int { 28 func (s *supportContext) numShards(k *ds.Key) int {
29 ret := DefaultShards 29 ret := DefaultShards
30 if s.shardsForKey != nil { 30 if s.shardsForKey != nil {
31 ret = s.shardsForKey(k) 31 ret = s.shardsForKey(k)
32 } 32 }
33 if ret < 1 { 33 if ret < 1 {
34 return 0 // disable caching entirely 34 return 0 // disable caching entirely
35 } 35 }
36 if ret > MaxShards { 36 if ret > MaxShards {
37 ret = MaxShards 37 ret = MaxShards
38 } 38 }
39 return ret 39 return ret
40 } 40 }
41 41
42 func (s *supportContext) mkRandKeys(keys []ds.Key, metas ds.MultiMetaGetter) []s tring { 42 func (s *supportContext) mkRandKeys(keys []*ds.Key, metas ds.MultiMetaGetter) [] string {
43 ret := []string(nil) 43 ret := []string(nil)
44 for i, key := range keys { 44 for i, key := range keys {
45 if !metas.GetMetaDefault(i, CacheEnableMeta, true).(bool) { 45 if !metas.GetMetaDefault(i, CacheEnableMeta, true).(bool) {
46 continue 46 continue
47 } 47 }
48 shards := s.numShards(key) 48 shards := s.numShards(key)
49 if shards == 0 { 49 if shards == 0 {
50 continue 50 continue
51 } 51 }
52 if ret == nil { 52 if ret == nil {
53 ret = make([]string, len(keys)) 53 ret = make([]string, len(keys))
54 } 54 }
55 ret[i] = MakeMemcacheKey(s.mr.Intn(shards), key) 55 ret[i] = MakeMemcacheKey(s.mr.Intn(shards), key)
56 } 56 }
57 return ret 57 return ret
58 } 58 }
59 59
60 func (s *supportContext) mkAllKeys(keys []ds.Key) []string { 60 func (s *supportContext) mkAllKeys(keys []*ds.Key) []string {
61 size := 0 61 size := 0
62 nums := make([]int, len(keys)) 62 nums := make([]int, len(keys))
63 for i, key := range keys { 63 for i, key := range keys {
64 if !key.Incomplete() { 64 if !key.Incomplete() {
65 shards := s.numShards(key) 65 shards := s.numShards(key)
66 nums[i] = shards 66 nums[i] = shards
67 size += shards 67 size += shards
68 } 68 }
69 } 69 }
70 if size == 0 { 70 if size == 0 {
(...skipping 24 matching lines...) Expand all
95 ret := make([]byte, NonceUint32s*4) 95 ret := make([]byte, NonceUint32s*4)
96 for w := uint(0); w < NonceUint32s; w++ { 96 for w := uint(0); w < NonceUint32s; w++ {
97 word := s.mr.Uint32() 97 word := s.mr.Uint32()
98 for i := uint(0); i < 4; i++ { 98 for i := uint(0); i < 4; i++ {
99 ret[(w*4)+i] = byte(word >> (8 * i)) 99 ret[(w*4)+i] = byte(word >> (8 * i))
100 } 100 }
101 } 101 }
102 return ret 102 return ret
103 } 103 }
104 104
105 func (s *supportContext) mutation(keys []ds.Key, f func() error) error { 105 func (s *supportContext) mutation(keys []*ds.Key, f func() error) error {
106 lockItems, lockKeys := s.mkAllLockItems(keys) 106 lockItems, lockKeys := s.mkAllLockItems(keys)
107 if lockItems == nil { 107 if lockItems == nil {
108 return f() 108 return f()
109 } 109 }
110 if err := s.mc.SetMulti(lockItems); err != nil { 110 if err := s.mc.SetMulti(lockItems); err != nil {
111 // this is a hard failure. No mutation can occur if we're unable to set 111 // this is a hard failure. No mutation can occur if we're unable to set
112 // locks out. See "DANGER ZONE" in the docs. 112 // locks out. See "DANGER ZONE" in the docs.
113 (log.Fields{log.ErrorKey: err}).Errorf( 113 (log.Fields{log.ErrorKey: err}).Errorf(
114 s.c, "dscache: HARD FAILURE: supportContext.mutation(): mc.SetMulti") 114 s.c, "dscache: HARD FAILURE: supportContext.mutation(): mc.SetMulti")
115 return err 115 return err
116 } 116 }
117 err := f() 117 err := f()
118 if err == nil { 118 if err == nil {
119 if err := s.mc.DeleteMulti(lockKeys); err != nil { 119 if err := s.mc.DeleteMulti(lockKeys); err != nil {
120 (log.Fields{log.ErrorKey: err}).Warningf( 120 (log.Fields{log.ErrorKey: err}).Warningf(
121 s.c, "dscache: mc.DeleteMulti") 121 s.c, "dscache: mc.DeleteMulti")
122 } 122 }
123 } 123 }
124 return err 124 return err
125 } 125 }
126 126
127 func (s *supportContext) mkRandLockItems(keys []ds.Key, metas ds.MultiMetaGetter ) ([]memcache.Item, []byte) { 127 func (s *supportContext) mkRandLockItems(keys []*ds.Key, metas ds.MultiMetaGette r) ([]memcache.Item, []byte) {
128 mcKeys := s.mkRandKeys(keys, metas) 128 mcKeys := s.mkRandKeys(keys, metas)
129 if len(mcKeys) == 0 { 129 if len(mcKeys) == 0 {
130 return nil, nil 130 return nil, nil
131 } 131 }
132 nonce := s.crappyNonce() 132 nonce := s.crappyNonce()
133 ret := make([]memcache.Item, len(mcKeys)) 133 ret := make([]memcache.Item, len(mcKeys))
134 for i, k := range mcKeys { 134 for i, k := range mcKeys {
135 if k == "" { 135 if k == "" {
136 continue 136 continue
137 } 137 }
138 ret[i] = (s.mc.NewItem(k). 138 ret[i] = (s.mc.NewItem(k).
139 SetFlags(uint32(ItemHasLock)). 139 SetFlags(uint32(ItemHasLock)).
140 SetExpiration(time.Second * time.Duration(LockTimeSecond s)). 140 SetExpiration(time.Second * time.Duration(LockTimeSecond s)).
141 SetValue(nonce)) 141 SetValue(nonce))
142 } 142 }
143 return ret, nonce 143 return ret, nonce
144 } 144 }
145 145
146 func (s *supportContext) mkAllLockItems(keys []ds.Key) ([]memcache.Item, []strin g) { 146 func (s *supportContext) mkAllLockItems(keys []*ds.Key) ([]memcache.Item, []stri ng) {
147 mcKeys := s.mkAllKeys(keys) 147 mcKeys := s.mkAllKeys(keys)
148 if mcKeys == nil { 148 if mcKeys == nil {
149 return nil, nil 149 return nil, nil
150 } 150 }
151 ret := make([]memcache.Item, len(mcKeys)) 151 ret := make([]memcache.Item, len(mcKeys))
152 for i := range ret { 152 for i := range ret {
153 ret[i] = (s.mc.NewItem(mcKeys[i]). 153 ret[i] = (s.mc.NewItem(mcKeys[i]).
154 SetFlags(uint32(ItemHasLock)). 154 SetFlags(uint32(ItemHasLock)).
155 SetExpiration(time.Second * time.Duration(LockTimeSecond s))) 155 SetExpiration(time.Second * time.Duration(LockTimeSecond s)))
156 } 156 }
157 return ret, mcKeys 157 return ret, mcKeys
158 } 158 }
OLDNEW
« no previous file with comments | « filter/dscache/plan.go ('k') | filter/featureBreaker/rds.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698