123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- using StackExchange.Redis;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using VCommon.Caching.Internals;
- using VCommon.Json;
- namespace VCommon.Caching
- {
- public class CacheManager
- {
- private readonly RedisCacheAccess _cacheAccess;
- public CacheManager(string server) => _cacheAccess = CacheAccess.CreateRedisAccessInstance(server);
- public void KeyExpire(int db, string key, CacheExpire expire)
- {
- if (null != expire)
- {
- if (expire.To.HasValue) _cacheAccess.CacheOp(db, p => p.KeyExpire(key, expire.To.Value));
- if (expire.Specified.HasValue) _cacheAccess.CacheOp(db, p => p.KeyExpire(key, expire.Specified.Value));
- }
- }
- public bool KeyExist(int db, string key) => _cacheAccess.CacheOp(db, p => p.KeyExists(key));
- public bool KeyDelete(int db, string key) => _cacheAccess.CacheOp(db, p => p.KeyDelete(key));
- public void KeySetJson(int db, string key, object value, CacheExpire expire = null)
- {
- var json = VJsonSerializer.Serialize(value);
- _cacheAccess.CacheOp(db, p => p.StringSet(key, json));
- KeyExpire(db, key, expire);
- }
- public T KeyGetJson<T>(int db, string key) => VJsonSerializer.Deserialize<T>(_cacheAccess.CacheOp(db, p => p.StringGet(key)));
- public void KeySet(int db, string key, CacheValue value, CacheExpire expire = null)
- {
- _cacheAccess.CacheOp(db, p => p.StringSet(key, value));
- KeyExpire(db, key, expire);
- }
- public CacheValue KeyGet(int db, string key) => _cacheAccess.CacheOp(db, p => p.StringGet(key));
- public bool HashFieldExist(int db, string hashKey, string hashField) => _cacheAccess.CacheOp(db, p => p.HashExists(hashKey, hashField));
- public bool HashFieldDelete(int db, string hashKey, string hashField) => _cacheAccess.CacheOp(db, p => p.HashDelete(hashKey, hashField));
- public long HashFieldDelete(int db, string hashKey, params string[] hashFields)
- {
- if (0 == hashFields.Length) return 0;
- var fields = hashFields.Select(p => (RedisValue)p).ToArray();
- return _cacheAccess.CacheOp(db, p => p.HashDelete(hashKey, fields));
- }
- public CacheValue HashFieldFetch(int db, string hashKey, string hashField, Func<CacheValue> missingCacheValueProvider, CacheExpire expire = null)
- {
- CacheValue cv = _cacheAccess.CacheOp(db, p => p.HashGet(hashKey, hashField));
- if (false == cv.IsNull) return cv;
- var through = missingCacheValueProvider();
- if (through.IsNull) return through;
- _cacheAccess.CacheOp(db, p => p.HashSet(hashKey, hashField, through));
- KeyExpire(db, hashKey, expire);
- return through;
- }
- public T HashFieldFetchJson<T>(int db, string hashKey, string hashField, Func<T> missingCacheValueProvider, CacheExpire expire = null)
- {
- string json = _cacheAccess.CacheOp(db, p => p.HashGet(hashKey, hashField));
- if (null != json) return VJsonSerializer.Deserialize<T>(json);
- var through = missingCacheValueProvider();
- var json2 = VJsonSerializer.Serialize(through);
- _cacheAccess.CacheOp(db, p => p.HashSet(hashKey, hashField, json2));
- KeyExpire(db, hashKey, expire);
- return through;
- }
- public T HashFieldGetJson<T>(int db, string hashKey, string hashField)
- {
- var json = (string)_cacheAccess.CacheOp(db, p => p.HashGet(hashKey, hashField));
- return VJsonSerializer.Deserialize<T>(json);
- }
- public void HashFieldSetJson<T>(int db, string hashKey, string hashField, T value, CacheExpire expire = null)
- {
- var json = VJsonSerializer.Serialize(value);
- _cacheAccess.CacheOp(db, p => p.HashSet(hashKey, hashField, json));
- KeyExpire(db, hashKey, expire);
- }
- public void HashFieldSetJson<T>(int db, string hashKey, IReadOnlyDictionary<string, T> entries, CacheExpire expire = null)
- {
- var hashEntrys = entries.Select(p => new HashEntry(p.Key, VJsonSerializer.Serialize(p.Value))).ToArray();
- _cacheAccess.CacheOp(db, p => p.HashSet(hashKey, hashEntrys));
- KeyExpire(db, hashKey, expire);
- }
- public void HashFieldPurgeAndSet(int db, string hashKey, IReadOnlyDictionary<string, CacheValue> hashFields)
- {
- var entries = hashFields.Select(p => new HashEntry(p.Key, p.Value)).ToArray();
- if (0 == entries.Length) return;
- _cacheAccess.CacheOp(db, p =>
- {
- var batch = p.CreateBatch();
- batch.KeyDeleteAsync(hashKey);
- batch.HashSetAsync(hashKey, entries);
- batch.Execute();
- });
- }
- public void HashFieldDeleteByPattern(int db, string hashKey, string pattern)
- {
- var entries = _cacheAccess.CacheOp(db, p => p.HashScan(hashKey, pattern, int.MaxValue)).Select(p => p.Name).ToArray();
- _cacheAccess.CacheOp(db, p => p.HashDelete(hashKey, entries));
- }
- public IReadOnlyDictionary<string, CacheValue> HashFieldGetByPattern(int db, string hashKey, string pattern)
- {
- return _cacheAccess.CacheOp(db, p => p.HashScan(hashKey, pattern, int.MaxValue))
- .ToDictionary(p => (string)p.Name, p => (CacheValue)p.Value);
- }
- public IReadOnlyDictionary<string, T> HashFieldGetByPatternJson<T>(int db, string hashKey, string pattern)
- {
- return _cacheAccess.CacheOp(db, p => p.HashScan(hashKey, pattern, int.MaxValue))
- .ToDictionary(p => (string)p.Name, p => VJsonSerializer.Deserialize<T>(p.Value));
- }
- public void HashFieldSet(int db, string hashKey, string hashField, CacheValue value, CacheExpire expire = null)
- {
- _cacheAccess.CacheOp(db, p => p.HashSet(hashKey, hashField, value));
- KeyExpire(db, hashKey, expire);
- }
- public CacheValue HashFieldGet(int db, string hashKey, string hashField) => _cacheAccess.CacheOp(db, p => p.HashGet(hashKey, hashField));
- public void HashFieldSet(int db, string hashKey, IReadOnlyDictionary<string, CacheValue> hashField, CacheExpire expire = null)
- {
- var entries = hashField.Select(p => new HashEntry(p.Key, p.Value)).ToArray();
- if (0 == entries.Length) return;
- _cacheAccess.CacheOp(db, p => p.HashSet(hashKey, entries));
- KeyExpire(db, hashKey, expire);
- }
- public long HashFieldIncrement(int db, string hashKey, string hashField) => _cacheAccess.CacheOp(db, p => p.HashIncrement(hashKey, hashField));
- public long HashFieldDecrement(int db, string hashKey, string hashField) => _cacheAccess.CacheOp(db, p => p.HashDecrement(hashKey, hashField));
- public IReadOnlyDictionary<string, CacheValue> HashFieldGet(int db, string hashKey, params string[] hashFields)
- {
- if (0 == hashFields.Length) return new Dictionary<string, CacheValue>();
- var keys = hashFields.Distinct().ToArray();
- var fields = keys.Select(p => (RedisValue)p).ToArray();
- return _cacheAccess.CacheOp(db, p => p.HashGet(hashKey, fields))
- .Select((p, i) => new { k = keys[i], v = p })
- .ToDictionary(p => p.k, p => (CacheValue)p.v);
- }
- public IReadOnlyDictionary<TK, TV> HashFieldsFetchAsDic<TK, TV>(int db, string key, IEnumerable<TK> hashFields,
- Func<TK, string> convertHashField,
- Func<IEnumerable<TK>, IReadOnlyDictionary<TK, TV>> missingCacheValueProvider,
- Func<TV, CacheValue> convertValueToCache,
- Func<CacheValue, TV> convertCacheToValue,
- CacheExpire expire = null)
- {
- var result = new Dictionary<TK, TV>();
- var missingFields = new List<TK>(); //get from cache,and collect missing
- {
- var fields = hashFields.Distinct().ToArray();
- if (0 == fields.Length) return result;
- var hf = fields.Select(p => (RedisValue)convertHashField(p)).ToArray();
- var fromCache = _cacheAccess.CacheOp(db, p => p.HashGet(key, hf));
- for (var i = 0; i < fromCache.Length; i++)
- {
- if (false == fromCache[i].HasValue) missingFields.Add(fields[i]);
- else result[fields[i]] = convertCacheToValue(fromCache[i]);
- }
- }
- if (0 != missingFields.Count) //get from db,and put cache
- {
- var fromDb = missingCacheValueProvider(missingFields);
- var entries = fromDb.Select(p => new HashEntry(convertHashField(p.Key), convertValueToCache(p.Value)))
- .Where(p => false == p.Value.IsNull)
- .ToArray();
- _cacheAccess.CacheOp(db, p => p.HashSet(key, entries));
- //merge to result
- foreach (var kvp in fromDb) result[kvp.Key] = kvp.Value;
- }
- KeyExpire(db, key, expire);
- return result;
- }
- public string[] SearchKeys(int db, string pattern) => _cacheAccess.SearchKeys(db, pattern).Select(p => (string)p).ToArray();
- }
- }
|