| 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 memory | 5 package memory |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/binary" | 8 "encoding/binary" |
| 9 "sync" | 9 "sync" |
| 10 "time" | 10 "time" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 func (m *mcItem) SetFlags(flg uint32) mc.Item { | 43 func (m *mcItem) SetFlags(flg uint32) mc.Item { |
| 44 m.flags = flg | 44 m.flags = flg |
| 45 return m | 45 return m |
| 46 } | 46 } |
| 47 func (m *mcItem) SetExpiration(exp time.Duration) mc.Item { | 47 func (m *mcItem) SetExpiration(exp time.Duration) mc.Item { |
| 48 m.expiration = exp | 48 m.expiration = exp |
| 49 return m | 49 return m |
| 50 } | 50 } |
| 51 | 51 |
| 52 func (m *mcItem) SetAll(other mc.Item) { | 52 func (m *mcItem) SetAll(other mc.Item) { |
| 53 » *m = *other.(*mcItem) | 53 » if other == nil { |
| 54 » » *m = mcItem{key: m.key} |
| 55 » } else { |
| 56 » » k := m.key |
| 57 » » *m = *other.(*mcItem) |
| 58 » » m.key = k |
| 59 » } |
| 54 } | 60 } |
| 55 | 61 |
| 56 type mcDataItem struct { | 62 type mcDataItem struct { |
| 57 value []byte | 63 value []byte |
| 58 flags uint32 | 64 flags uint32 |
| 59 expiration time.Time | 65 expiration time.Time |
| 60 casID uint64 | 66 casID uint64 |
| 61 } | 67 } |
| 62 | 68 |
| 63 func (m *mcDataItem) toUserItem(key string) *mcItem { | 69 func (m *mcDataItem) toUserItem(key string) *mcItem { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 data *memcacheData | 150 data *memcacheData |
| 145 ctx context.Context | 151 ctx context.Context |
| 146 } | 152 } |
| 147 | 153 |
| 148 var _ mc.RawInterface = (*memcacheImpl)(nil) | 154 var _ mc.RawInterface = (*memcacheImpl)(nil) |
| 149 | 155 |
| 150 // useMC adds a gae.Memcache implementation to context, accessible | 156 // useMC adds a gae.Memcache implementation to context, accessible |
| 151 // by gae.GetMC(c) | 157 // by gae.GetMC(c) |
| 152 func useMC(c context.Context) context.Context { | 158 func useMC(c context.Context) context.Context { |
| 153 lck := sync.Mutex{} | 159 lck := sync.Mutex{} |
| 160 // TODO(riannucci): just use namespace for automatic key prefixing. Flus
h |
| 161 // actually wipes the ENTIRE memcache, regardless of namespace. |
| 154 mcdMap := map[string]*memcacheData{} | 162 mcdMap := map[string]*memcacheData{} |
| 155 | 163 |
| 156 return mc.SetRawFactory(c, func(ic context.Context) mc.RawInterface { | 164 return mc.SetRawFactory(c, func(ic context.Context) mc.RawInterface { |
| 157 lck.Lock() | 165 lck.Lock() |
| 158 defer lck.Unlock() | 166 defer lck.Unlock() |
| 159 | 167 |
| 160 ns := curGID(ic).namespace | 168 ns := curGID(ic).namespace |
| 161 mcd, ok := mcdMap[ns] | 169 mcd, ok := mcdMap[ns] |
| 162 if !ok { | 170 if !ok { |
| 163 mcd = &memcacheData{items: map[string]*mcDataItem{}} | 171 mcd = &memcacheData{items: map[string]*mcDataItem{}} |
| (...skipping 29 matching lines...) Expand all Loading... |
| 193 | 201 |
| 194 func (m *memcacheImpl) AddMulti(items []mc.Item, cb mc.RawCB) error { | 202 func (m *memcacheImpl) AddMulti(items []mc.Item, cb mc.RawCB) error { |
| 195 now := clock.Now(m.ctx) | 203 now := clock.Now(m.ctx) |
| 196 doCBs(items, cb, func(itm mc.Item) error { | 204 doCBs(items, cb, func(itm mc.Item) error { |
| 197 m.data.lock.Lock() | 205 m.data.lock.Lock() |
| 198 defer m.data.lock.Unlock() | 206 defer m.data.lock.Unlock() |
| 199 if !m.data.hasItemLocked(now, itm.Key()) { | 207 if !m.data.hasItemLocked(now, itm.Key()) { |
| 200 m.data.setItemLocked(now, itm) | 208 m.data.setItemLocked(now, itm) |
| 201 return nil | 209 return nil |
| 202 } else { | 210 } else { |
| 203 » » » return (mc.ErrNotStored) | 211 » » » return mc.ErrNotStored |
| 204 } | 212 } |
| 205 }) | 213 }) |
| 206 return nil | 214 return nil |
| 207 } | 215 } |
| 208 | 216 |
| 209 func (m *memcacheImpl) CompareAndSwapMulti(items []mc.Item, cb mc.RawCB) error { | 217 func (m *memcacheImpl) CompareAndSwapMulti(items []mc.Item, cb mc.RawCB) error { |
| 210 now := clock.Now(m.ctx) | 218 now := clock.Now(m.ctx) |
| 211 doCBs(items, cb, func(itm mc.Item) error { | 219 doCBs(items, cb, func(itm mc.Item) error { |
| 212 m.data.lock.Lock() | 220 m.data.lock.Lock() |
| 213 defer m.data.lock.Unlock() | 221 defer m.data.lock.Unlock() |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 return cur, nil | 343 return cur, nil |
| 336 } | 344 } |
| 337 | 345 |
| 338 func (m *memcacheImpl) Stats() (*mc.Statistics, error) { | 346 func (m *memcacheImpl) Stats() (*mc.Statistics, error) { |
| 339 m.data.lock.RLock() | 347 m.data.lock.RLock() |
| 340 defer m.data.lock.RUnlock() | 348 defer m.data.lock.RUnlock() |
| 341 | 349 |
| 342 ret := m.data.stats | 350 ret := m.data.stats |
| 343 return &ret, nil | 351 return &ret, nil |
| 344 } | 352 } |
| OLD | NEW |