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 memcache | 5 package memcache |
6 | 6 |
7 import ( | 7 import ( |
8 "github.com/luci/luci-go/common/errors" | 8 "github.com/luci/luci-go/common/errors" |
9 "golang.org/x/net/context" | 9 "golang.org/x/net/context" |
10 ) | 10 ) |
(...skipping 15 matching lines...) Expand all Loading... |
26 } | 26 } |
27 | 27 |
28 func (m *memcacheImpl) Delete(key string) error { | 28 func (m *memcacheImpl) Delete(key string) error { |
29 return errors.SingleError(m.DeleteMulti([]string{key})) | 29 return errors.SingleError(m.DeleteMulti([]string{key})) |
30 } | 30 } |
31 | 31 |
32 func (m *memcacheImpl) CompareAndSwap(item Item) error { | 32 func (m *memcacheImpl) CompareAndSwap(item Item) error { |
33 return errors.SingleError(m.CompareAndSwapMulti([]Item{item})) | 33 return errors.SingleError(m.CompareAndSwapMulti([]Item{item})) |
34 } | 34 } |
35 | 35 |
36 func multiCall(items []Item, inner func(items []Item, cb RawCB) error) error { | 36 func filterItems(lme *errors.LazyMultiError, items []Item, nilErr error) ([]Item
, []int) { |
| 37 » idxMap := make([]int, 0, len(items)) |
| 38 » retItems := make([]Item, 0, len(items)) |
| 39 » for i, itm := range items { |
| 40 » » if itm != nil { |
| 41 » » » idxMap = append(idxMap, i) |
| 42 » » » retItems = append(retItems, itm) |
| 43 » » } else { |
| 44 » » » lme.Assign(i, nilErr) |
| 45 » » } |
| 46 » } |
| 47 » return retItems, idxMap |
| 48 } |
| 49 |
| 50 func multiCall(items []Item, nilErr error, inner func(items []Item, cb RawCB) er
ror) error { |
37 lme := errors.LazyMultiError{Size: len(items)} | 51 lme := errors.LazyMultiError{Size: len(items)} |
38 » i := 0 | 52 » realItems, idxMap := filterItems(&lme, items, nilErr) |
39 » err := inner(items, func(err error) { | 53 » j := 0 |
40 » » lme.Assign(i, err) | 54 » err := inner(realItems, func(err error) { |
41 » » i++ | 55 » » lme.Assign(idxMap[j], err) |
| 56 » » j++ |
42 }) | 57 }) |
43 if err == nil { | 58 if err == nil { |
44 err = lme.Get() | 59 err = lme.Get() |
45 } | 60 } |
46 return err | 61 return err |
47 } | 62 } |
48 | 63 |
49 func (m *memcacheImpl) AddMulti(items []Item) error { | 64 func (m *memcacheImpl) AddMulti(items []Item) error { |
50 » return multiCall(items, m.RawInterface.AddMulti) | 65 » return multiCall(items, ErrNotStored, m.RawInterface.AddMulti) |
51 } | 66 } |
52 | 67 |
53 func (m *memcacheImpl) SetMulti(items []Item) error { | 68 func (m *memcacheImpl) SetMulti(items []Item) error { |
54 » return multiCall(items, m.RawInterface.SetMulti) | 69 » return multiCall(items, ErrNotStored, m.RawInterface.SetMulti) |
55 } | 70 } |
56 | 71 |
57 func (m *memcacheImpl) CompareAndSwapMulti(items []Item) error { | 72 func (m *memcacheImpl) CompareAndSwapMulti(items []Item) error { |
58 » return multiCall(items, m.RawInterface.CompareAndSwapMulti) | 73 » return multiCall(items, ErrNotStored, m.RawInterface.CompareAndSwapMulti
) |
59 } | 74 } |
60 | 75 |
61 func (m *memcacheImpl) DeleteMulti(keys []string) error { | 76 func (m *memcacheImpl) DeleteMulti(keys []string) error { |
62 lme := errors.LazyMultiError{Size: len(keys)} | 77 lme := errors.LazyMultiError{Size: len(keys)} |
63 i := 0 | 78 i := 0 |
64 err := m.RawInterface.DeleteMulti(keys, func(err error) { | 79 err := m.RawInterface.DeleteMulti(keys, func(err error) { |
65 lme.Assign(i, err) | 80 lme.Assign(i, err) |
66 i++ | 81 i++ |
67 }) | 82 }) |
68 if err == nil { | 83 if err == nil { |
69 err = lme.Get() | 84 err = lme.Get() |
70 } | 85 } |
71 return err | 86 return err |
72 } | 87 } |
73 | 88 |
74 func (m *memcacheImpl) GetMulti(items []Item) error { | 89 func (m *memcacheImpl) GetMulti(items []Item) error { |
75 lme := errors.LazyMultiError{Size: len(items)} | 90 lme := errors.LazyMultiError{Size: len(items)} |
76 » i := 0 | 91 » realItems, idxMap := filterItems(&lme, items, ErrCacheMiss) |
77 » keys := make([]string, len(items)) | 92 » if len(realItems) == 0 { |
78 » for i, itm := range items { | 93 » » return lme.Get() |
| 94 » } |
| 95 |
| 96 » keys := make([]string, len(realItems)) |
| 97 » for i, itm := range realItems { |
79 keys[i] = itm.Key() | 98 keys[i] = itm.Key() |
80 } | 99 } |
| 100 |
| 101 j := 0 |
81 err := m.RawInterface.GetMulti(keys, func(item Item, err error) { | 102 err := m.RawInterface.GetMulti(keys, func(item Item, err error) { |
| 103 i := idxMap[j] |
82 if !lme.Assign(i, err) { | 104 if !lme.Assign(i, err) { |
83 items[i].SetAll(item) | 105 items[i].SetAll(item) |
84 } | 106 } |
85 » » i++ | 107 » » j++ |
86 }) | 108 }) |
87 if err == nil { | 109 if err == nil { |
88 err = lme.Get() | 110 err = lme.Get() |
89 } | 111 } |
90 return err | 112 return err |
91 } | 113 } |
92 | 114 |
93 func (m *memcacheImpl) Increment(key string, delta int64, initialValue uint64) (
newValue uint64, err error) { | 115 func (m *memcacheImpl) Increment(key string, delta int64, initialValue uint64) (
newValue uint64, err error) { |
94 return m.RawInterface.Increment(key, delta, &initialValue) | 116 return m.RawInterface.Increment(key, delta, &initialValue) |
95 } | 117 } |
96 | 118 |
97 func (m *memcacheImpl) IncrementExisting(key string, delta int64) (newValue uint
64, err error) { | 119 func (m *memcacheImpl) IncrementExisting(key string, delta int64) (newValue uint
64, err error) { |
98 return m.RawInterface.Increment(key, delta, nil) | 120 return m.RawInterface.Increment(key, delta, nil) |
99 } | 121 } |
100 | 122 |
101 func (m *memcacheImpl) Raw() RawInterface { return m.RawInterface } | 123 func (m *memcacheImpl) Raw() RawInterface { return m.RawInterface } |
102 | 124 |
103 // Get gets the current memcache implementation from the context. | 125 // Get gets the current memcache implementation from the context. |
104 func Get(c context.Context) Interface { | 126 func Get(c context.Context) Interface { |
105 return &memcacheImpl{GetRaw(c)} | 127 return &memcacheImpl{GetRaw(c)} |
106 } | 128 } |
OLD | NEW |