Index: memory/memcache.go |
diff --git a/memory/memcache.go b/memory/memcache.go |
deleted file mode 100644 |
index 82efe4b4df4f4fa8978256104fefde2f8b8caacb..0000000000000000000000000000000000000000 |
--- a/memory/memcache.go |
+++ /dev/null |
@@ -1,203 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-package memory |
- |
-import ( |
- "sync" |
- "time" |
- |
- "golang.org/x/net/context" |
- |
- "github.com/luci/gae" |
- "github.com/luci/gae/dummy" |
- |
- "github.com/luci/luci-go/common/clock" |
-) |
- |
-type mcItem struct { |
- key string |
- value []byte |
- object interface{} |
- flags uint32 |
- expiration time.Duration |
- |
- CasID uint64 |
-} |
- |
-var _ gae.MCItem = (*mcItem)(nil) |
- |
-func (m *mcItem) Key() string { return m.key } |
-func (m *mcItem) Value() []byte { return m.value } |
-func (m *mcItem) Object() interface{} { return m.object } |
-func (m *mcItem) Flags() uint32 { return m.flags } |
-func (m *mcItem) Expiration() time.Duration { return m.expiration } |
- |
-func (m *mcItem) SetKey(key string) gae.MCItem { |
- m.key = key |
- return m |
-} |
-func (m *mcItem) SetValue(val []byte) gae.MCItem { |
- m.value = val |
- return m |
-} |
-func (m *mcItem) SetObject(obj interface{}) gae.MCItem { |
- m.object = obj |
- return m |
-} |
-func (m *mcItem) SetFlags(flg uint32) gae.MCItem { |
- m.flags = flg |
- return m |
-} |
-func (m *mcItem) SetExpiration(exp time.Duration) gae.MCItem { |
- m.expiration = exp |
- return m |
-} |
- |
-func (m *mcItem) duplicate() *mcItem { |
- ret := mcItem{} |
- ret = *m |
- ret.value = make([]byte, len(m.value)) |
- copy(ret.value, m.value) |
- return &ret |
-} |
- |
-type memcacheData struct { |
- lock sync.Mutex |
- items map[string]*mcItem |
- casID uint64 |
-} |
- |
-// memcacheImpl binds the current connection's memcache data to an |
-// implementation of {gae.Memcache, gae.Testable}. |
-type memcacheImpl struct { |
- gae.Memcache |
- |
- data *memcacheData |
- ctx context.Context |
-} |
- |
-var _ gae.Memcache = (*memcacheImpl)(nil) |
- |
-// useMC adds a gae.Memcache implementation to context, accessible |
-// by gae.GetMC(c) |
-func useMC(c context.Context) context.Context { |
- lck := sync.Mutex{} |
- mcdMap := map[string]*memcacheData{} |
- |
- return gae.SetMCFactory(c, func(ic context.Context) gae.Memcache { |
- lck.Lock() |
- defer lck.Unlock() |
- |
- ns := curGID(ic).namespace |
- mcd, ok := mcdMap[ns] |
- if !ok { |
- mcd = &memcacheData{items: map[string]*mcItem{}} |
- mcdMap[ns] = mcd |
- } |
- |
- return &memcacheImpl{ |
- dummy.MC(), |
- mcd, |
- ic, |
- } |
- }) |
-} |
- |
-func (m *memcacheImpl) mkItemLocked(i gae.MCItem) (ret *mcItem) { |
- m.data.casID++ |
- |
- var exp time.Duration |
- if i.Expiration() != 0 { |
- exp = time.Duration(clock.Now(m.ctx).Add(i.Expiration()).UnixNano()) |
- } |
- newItem := mcItem{ |
- key: i.Key(), |
- flags: i.Flags(), |
- expiration: exp, |
- value: i.Value(), |
- CasID: m.data.casID, |
- } |
- return newItem.duplicate() |
-} |
- |
-func (m *memcacheImpl) NewItem(key string) gae.MCItem { |
- return &mcItem{key: key} |
-} |
- |
-// Add implements context.MCSingleReadWriter.Add. |
-func (m *memcacheImpl) Add(i gae.MCItem) error { |
- m.data.lock.Lock() |
- defer m.data.lock.Unlock() |
- |
- if _, ok := m.retrieveLocked(i.Key()); !ok { |
- m.data.items[i.Key()] = m.mkItemLocked(i) |
- return nil |
- } |
- return gae.ErrMCNotStored |
-} |
- |
-// CompareAndSwap implements context.MCSingleReadWriter.CompareAndSwap. |
-func (m *memcacheImpl) CompareAndSwap(item gae.MCItem) error { |
- m.data.lock.Lock() |
- defer m.data.lock.Unlock() |
- |
- if cur, ok := m.retrieveLocked(item.Key()); ok { |
- casid := uint64(0) |
- if mi, ok := item.(*mcItem); ok && mi != nil { |
- casid = mi.CasID |
- } |
- |
- if cur.CasID == casid { |
- m.data.items[item.Key()] = m.mkItemLocked(item) |
- } else { |
- return gae.ErrMCCASConflict |
- } |
- } else { |
- return gae.ErrMCNotStored |
- } |
- return nil |
-} |
- |
-// Set implements context.MCSingleReadWriter.Set. |
-func (m *memcacheImpl) Set(i gae.MCItem) error { |
- m.data.lock.Lock() |
- defer m.data.lock.Unlock() |
- m.data.items[i.Key()] = m.mkItemLocked(i) |
- return nil |
-} |
- |
-// Get implements context.MCSingleReadWriter.Get. |
-func (m *memcacheImpl) Get(key string) (itm gae.MCItem, err error) { |
- m.data.lock.Lock() |
- defer m.data.lock.Unlock() |
- if val, ok := m.retrieveLocked(key); ok { |
- itm = val.duplicate().SetExpiration(0) |
- } else { |
- err = gae.ErrMCCacheMiss |
- } |
- return |
-} |
- |
-// Delete implements context.MCSingleReadWriter.Delete. |
-func (m *memcacheImpl) Delete(key string) error { |
- m.data.lock.Lock() |
- defer m.data.lock.Unlock() |
- |
- if _, ok := m.retrieveLocked(key); ok { |
- delete(m.data.items, key) |
- return nil |
- } |
- return gae.ErrMCCacheMiss |
-} |
- |
-func (m *memcacheImpl) retrieveLocked(key string) (*mcItem, bool) { |
- ret, ok := m.data.items[key] |
- if ok && ret.Expiration() != 0 && ret.Expiration() < time.Duration(clock.Now(m.ctx).UnixNano()) { |
- ret = nil |
- ok = false |
- delete(m.data.items, key) |
- } |
- return ret, ok |
-} |