Skip to content

Commit

Permalink
fix: update cache
Browse files Browse the repository at this point in the history
  • Loading branch information
yusank committed Jul 6, 2022
1 parent bf00194 commit 8a641b5
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 4 deletions.
15 changes: 15 additions & 0 deletions pkg/cache/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,23 @@ import (
)

type Cache interface {
// string

Get(ctx context.Context, key string) ([]byte, error)
Set(ctx context.Context, key string, value []byte, expire time.Duration) error
Delete(ctx context.Context, key string) error

// set

IsInSet(ctx context.Context, key string, member string) (bool, error)
AddToSet(ctx context.Context, key string, member string) error
DeleteFromSet(ctx context.Context, key string, member string) error

// hashmap

GetFromHash(ctx context.Context, key string, field string) ([]byte, error)
SetToHash(ctx context.Context, key string, field string, value []byte) error
DeleteFromHash(ctx context.Context, key string, field string) error

Close(ctx context.Context) error
}
43 changes: 43 additions & 0 deletions pkg/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var (
var (
ErrCacheMiss = errors.New("cache miss")
ErrCacheFull = errors.New("cache full")
ErrKeyType = errors.New("invalid key type")
)

// SetGlobalCache sets the global cache.
Expand All @@ -25,6 +26,10 @@ func GetGlobalCache() Cache {
return globalCache
}

/*
* string
*/

// Get is wrapper for global cache.Get.
func Get(ctx context.Context, key string) ([]byte, error) {
return globalCache.Get(ctx, key)
Expand All @@ -40,6 +45,44 @@ func Delete(ctx context.Context, key string) error {
return globalCache.Delete(ctx, key)
}

/*
* set
*/

// IsInSet is wrapper for global cache.IsInSet.
func IsInSet(ctx context.Context, key string, member string) (bool, error) {
return globalCache.IsInSet(ctx, key, member)
}

// AddToSet is wrapper for global cache.AddToSet.
func AddToSet(ctx context.Context, key string, member string) error {
return globalCache.AddToSet(ctx, key, member)
}

// DeleteFromSet is wrapper for global cache.DeleteFromSet.
func DeleteFromSet(ctx context.Context, key string, member string) error {
return globalCache.DeleteFromSet(ctx, key, member)
}

/*
* hashmap
*/

// GetFromHash is wrapper for global cache.GetFromHash.
func GetFromHash(ctx context.Context, key string, field string) ([]byte, error) {
return globalCache.GetFromHash(ctx, key, field)
}

// SetToHash is wrapper for global cache.SetToHash.
func SetToHash(ctx context.Context, key string, field string, value []byte) error {
return globalCache.SetToHash(ctx, key, field, value)
}

// DeleteFromHash is wrapper for global cache.DeleteFromHash.
func DeleteFromHash(ctx context.Context, key string, field string) error {
return globalCache.DeleteFromHash(ctx, key, field)
}

// Close is wrapper for global cache.Close.
func Close(ctx context.Context) error {
return globalCache.Close(ctx)
Expand Down
158 changes: 158 additions & 0 deletions pkg/cache/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,164 @@ func (m *memoryCache) Delete(_ context.Context, key string) error {
return nil
}

/*
* set
*/

type set struct {
items map[string]bool
}

func (s *set) has(key string) bool {
_, ok := s.items[key]
return ok
}

func (s *set) add(key string) {
s.items[key] = true
}

func (m *memoryCache) IsInSet(_ context.Context, key string, member string) (bool, error) {
m.mu.RLock()
defer m.mu.RUnlock()

item, ok := m.items[key]
if !ok {
return false, ErrCacheMiss
}

s := item.value.(*set)
return s.has(member), nil
}

func (m *memoryCache) AddToSet(_ context.Context, key string, member string) error {
m.mu.Lock()
defer m.mu.Unlock()

item, ok := m.items[key]
if !ok {
return ErrCacheMiss
}

s := item.value.(*set)
if s.has(member) {
return nil
}

s.add(member)
return nil
}

func (m *memoryCache) DeleteFromSet(_ context.Context, key string, member string) error {
m.mu.Lock()
defer m.mu.Unlock()

item, ok := m.items[key]
if !ok {
return ErrCacheMiss
}

s := item.value.(*set)
if !s.has(member) {
return nil
}

delete(s.items, member)
return nil
}

/*
* hashmap
*/

type hashmap struct {
items map[string]map[string][]byte
}

func (h *hashmap) set(key string, field string, value []byte) {
if _, ok := h.items[key]; !ok {
h.items[key] = make(map[string][]byte)
}
h.items[key][field] = value
}

func (h *hashmap) get(key string, field string) ([]byte, bool) {
if _, ok := h.items[key]; !ok {
return nil, false
}

value, ok := h.items[key][field]
return value, ok
}

func (m *memoryCache) GetFromHash(_ context.Context, key string, field string) ([]byte, error) {
m.mu.RLock()
defer m.mu.RUnlock()

item, ok := m.items[key]
if !ok {
return nil, ErrCacheMiss
}

h, ok := item.value.(*hashmap)
if !ok {
return nil, ErrKeyType
}

value, ok := h.get(key, field)
if !ok {
return nil, ErrCacheMiss
}

return value, nil
}

func (m *memoryCache) SetToHash(_ context.Context, key string, field string, value []byte) error {
m.mu.Lock()
defer m.mu.Unlock()

h := &hashmap{
items: make(map[string]map[string][]byte),
}
item, ok := m.items[key]
if ok {
h, ok = item.value.(*hashmap)
if !ok {
return ErrKeyType
}
} else {
m.items[key] = &memoryCacheItem{
value: h,
}
}

h.set(key, field, value)
return nil
}

func (m *memoryCache) DeleteFromHash(_ context.Context, key string, field string) error {
m.mu.Lock()
defer m.mu.Unlock()

item, ok := m.items[key]
if !ok {
return ErrCacheMiss
}

h, ok := item.value.(*hashmap)
if !ok {
return ErrKeyType
}

_, ok = h.items[key]
if !ok {
return ErrCacheMiss
}

delete(h.items[key], field)
return nil
}

func (m *memoryCache) Close(_ context.Context) error {
m.mu.Lock()
defer m.mu.Unlock()
Expand Down
88 changes: 85 additions & 3 deletions pkg/cache/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ func (r *redisCache) Get(ctx context.Context, key string) ([]byte, error) {
ctx = context.Background()
}

b, err := r.client.Get(ctx, key).Bytes()
ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

b, err := r.client.Get(ctx2, key).Bytes()
if err != nil {
if err == redisv8.Nil {
return nil, ErrCacheMiss
Expand All @@ -43,16 +46,21 @@ func (r *redisCache) Set(ctx context.Context, key string, value []byte, expire t
if ctx == nil {
ctx = context.Background()
}
ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

return r.client.Set(ctx, key, value, expire).Err()
return r.client.Set(ctx2, key, value, expire).Err()
}

func (r *redisCache) Delete(ctx context.Context, key string) error {
if ctx == nil {
ctx = context.Background()
}

err := r.client.Del(ctx, key).Err()
ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

err := r.client.Del(ctx2, key).Err()
if err != nil {
if err == redisv8.Nil {
return nil
Expand All @@ -63,6 +71,80 @@ func (r *redisCache) Delete(ctx context.Context, key string) error {
return nil
}

func (r *redisCache) IsInSet(ctx context.Context, key string, member string) (bool, error) {
if ctx == nil {
ctx = context.Background()
}

ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

return r.client.SIsMember(ctx2, key, member).Val(), nil
}

func (r *redisCache) AddToSet(ctx context.Context, key string, member string) error {
if ctx == nil {
ctx = context.Background()
}

ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

return r.client.SAdd(ctx2, key, member).Err()
}

func (r *redisCache) DeleteFromSet(ctx context.Context, key string, member string) error {
if ctx == nil {
ctx = context.Background()
}

ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

return r.client.SRem(ctx2, key, member).Err()
}

func (r *redisCache) GetFromHash(ctx context.Context, key string, field string) ([]byte, error) {
if ctx == nil {
ctx = context.Background()
}

ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

b, err := r.client.HGet(ctx2, key, field).Bytes()
if err != nil {
if err == redisv8.Nil {
return nil, ErrCacheMiss
}

return nil, err
}

return b, nil
}

func (r *redisCache) SetToHash(ctx context.Context, key string, field string, value []byte) error {
if ctx == nil {
ctx = context.Background()
}
ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

return r.client.HSet(ctx2, key, field, value).Err()
}

func (r *redisCache) DeleteFromHash(ctx context.Context, key string, field string) error {
if ctx == nil {
ctx = context.Background()
}

ctx2, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

return r.client.HDel(ctx2, key, field).Err()
}

func (r *redisCache) Close(_ context.Context) error {
return r.client.Close()
}
2 changes: 1 addition & 1 deletion pkg/mid/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func SetJwtToHeader(c *gin.Context, userID string) error {
return nil
}

func AuthJwtCookie(c *gin.Context) {
func AuthJwt(c *gin.Context) {
token := c.Request.Header.Get("Authorization")
if token == "" {
c.AbortWithStatus(401)
Expand Down
5 changes: 5 additions & 0 deletions pkg/util/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package util

func IsGroupUID(uid string) bool {
return len(uid) > 1 && uid[:2] == "g_"
}

0 comments on commit 8a641b5

Please sign in to comment.