gitee.com/go-spring2/spring-base@v1.1.3/cache/cache.go (about) 1 /* 2 * Copyright 2012-2019 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Package cache provides object caching in memory. 18 package cache 19 20 import ( 21 "context" 22 "sync" 23 "time" 24 ) 25 26 var ( 27 Cache Shardable 28 Engine Driver 29 ) 30 31 func init() { 32 Cache = NewStorage(1, SimpleHash) 33 Engine = &engine{} 34 } 35 36 // A Shardable cache can improve the performance of concurrency. 37 type Shardable interface { 38 Sharding(key string) *sync.Map 39 } 40 41 type LoadType int 42 43 const ( 44 LoadNone LoadType = iota 45 LoadOnCtx 46 LoadCache 47 LoadSource 48 ) 49 50 // ResultLoader returns a wrapper for the source value of the key. 51 type ResultLoader func(ctx context.Context, key string) (Result, error) 52 53 // Driver loads value from m, if there is no cached value, call the loader 54 // to get value, and then stores it into m. 55 type Driver interface { 56 Load(ctx context.Context, m *sync.Map, key string, loader ResultLoader, arg OptionArg) (loadType LoadType, result Result, err error) 57 } 58 59 // Has returns whether the key exists. 60 func Has(key string) bool { 61 v, ok := Cache.Sharding(key).Load(key) 62 if ok && v != nil { 63 return !v.(*cacheItem).expired() 64 } 65 return false 66 } 67 68 type OptionArg struct { 69 ExpireAfterWrite time.Duration 70 } 71 72 type Option func(*OptionArg) 73 74 // ExpireAfterWrite sets the expiration time of the cache value after write. 75 func ExpireAfterWrite(v time.Duration) Option { 76 return func(arg *OptionArg) { 77 arg.ExpireAfterWrite = v 78 } 79 } 80 81 // Loader gets value from a background, such as Redis, MySQL, etc. 82 type Loader func(ctx context.Context, key string) (interface{}, error) 83 84 // Load loads value from cache, if there is no cached value, call the loader 85 // to get value, and then stores it. 86 func Load(ctx context.Context, key string, loader Loader, opts ...Option) (loadType LoadType, result Result, _ error) { 87 arg := OptionArg{} 88 for _, opt := range opts { 89 opt(&arg) 90 } 91 l := func(ctx context.Context, key string) (Result, error) { 92 v, err := loader(ctx, key) 93 if err != nil { 94 return nil, err 95 } 96 return NewValueResult(v), nil 97 } 98 m := Cache.Sharding(key) 99 return Engine.Load(ctx, m, key, l, arg) 100 }