/// <summary> /// 查找所有匹配数据 /// </summary> /// <param name="personalId"></param> /// <param name="match"></param> /// <param name="isSort"></param> /// <param name="list"></param> /// <returns></returns> public LoadingStatus TryFindAll(string personalId, Predicate <T> match, bool isSort, out List <T> list) { LoadingStatus loadStatus; List <T> tempList = new List <T>(); BaseCollection collection; personalId = AbstractEntity.EncodeKeyCode(personalId); if (TryGetGroup(personalId, out collection, out loadStatus)) { collection.Foreach <T>((key, value) => { if (match == null || match(value)) { tempList.Add(value); } return(true); }); } list = tempList; if (isSort) { list.QuickSort(); } return(loadStatus); }
/// <summary> /// Get entity from redis, but not surported mutil key of entity. /// </summary> /// <param name="personalId"></param> /// <param name="types"></param> /// <returns></returns> public static object[] Load(string personalId, params Type[] types) { personalId = AbstractEntity.EncodeKeyCode(personalId); var param = types.Where(t => !CacheFactory.ContainEntityKey(t, personalId)).ToArray(); if (param.Length == 0) { return(null); } var result = RedisConnectionPool.GetAllEntity(personalId, param); foreach (var t in result) { var entity = t as AbstractEntity; if (entity == null) { continue; } CacheItemSet itemSet; if (CacheFactory.AddOrUpdateEntity(entity, out itemSet)) { itemSet.OnLoadSuccess(); } } return(result); }
/// <summary> /// /// </summary> /// <param name="personalId"></param> /// <param name="data"></param> /// <param name="keys"></param> /// <returns></returns> public LoadingStatus TryFindKey(string personalId, out T data, params object[] keys) { LoadingStatus loadStatus; BaseCollection collection; data = default(T); personalId = AbstractEntity.EncodeKeyCode(personalId); if (TryGetGroup(personalId, out collection, out loadStatus)) { string key = keys.Length > 0 ? AbstractEntity.CreateKeyCode(keys) : personalId; if (!collection.TryGetValue(key, out data)) { //修正旧版本无personalId参数调用 var tempKeys = new List <object>(); tempKeys.Add(personalId); if (keys.Length > 0) { tempKeys.AddRange(keys); } key = string.IsNullOrEmpty(key) ? personalId : AbstractEntity.CreateKeyCode(tempKeys.ToArray()); collection.TryGetValue(key, out data); } } return(loadStatus); }
/// <summary> /// 是否存在数据 /// </summary> /// <param name="personalId"></param> /// <returns></returns> public bool IsExistData(string personalId) { LoadingStatus loadStatus; BaseCollection enityGroup; personalId = AbstractEntity.EncodeKeyCode(personalId); return(TryGetGroup(personalId, out enityGroup, out loadStatus)); }
/// <summary> /// 自动加载 /// </summary> /// <param name="personalId">私有分组ID</param> /// <returns></returns> public bool AutoLoad(string personalId) { personalId = AbstractEntity.EncodeKeyCode(personalId); if (!IsExistData(personalId)) { return(TryLoadItem(personalId, false)); } return(true); }
/// <summary> /// /// </summary> /// <param name="personalId"></param> /// <param name="match"></param> /// <param name="hasChanged"></param> public static void Update(string personalId, Predicate <SchemaTable> match, bool hasChanged = false) { personalId = AbstractEntity.EncodeKeyCode(personalId); foreach (var schemaTable in EntitySchemaSet.GetEnumerable()) { if (match(schemaTable)) { Update(personalId, schemaTable, hasChanged); } } }
/// <summary> /// /// </summary> public static void ReLoad(string personalId, Predicate <SchemaTable> match) { personalId = AbstractEntity.EncodeKeyCode(personalId); foreach (var schemaTable in EntitySchemaSet.GetEnumerable()) { if (match(schemaTable)) { ReLoad(personalId, schemaTable); } } }
/// <summary> /// 获取缓存对象 /// </summary> /// <param name="personalId"></param> /// <returns></returns> public BaseCollection GetCache(string personalId) { LoadingStatus loadStatus; BaseCollection collection; personalId = AbstractEntity.EncodeKeyCode(personalId); if (TryGetGroup(personalId, out collection, out loadStatus)) { return(collection); } return(null); }
/// <summary> /// Get entity of personal object /// </summary> /// <param name="entityType"></param> /// <param name="personalId"></param> /// <param name="keys"></param> /// <returns></returns> public static dynamic GetPersonalEntity(string entityType, string personalId, params object[] keys) { string key = AbstractEntity.EncodeKeyCode(personalId); if (keys.Length > 0) { key += "|" + AbstractEntity.CreateKeyCode(keys); } string redisKey = string.Format("{0}_{1}", RedisConnectionPool.EncodeTypeName(entityType), key); CacheItemSet itemSet; return(GetPersonalEntity(redisKey, out itemSet)); }
/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="key"></param> /// <returns></returns> public static bool ContainEntityKey(Type type, string key) { CacheContainer container; key = AbstractEntity.EncodeKeyCode(key); if (_writePools != null && _writePools.TryGetValue(type.FullName, out container)) { CacheItemSet itemSet; return(container.Collection.TryGetValue(key, out itemSet) && itemSet.LoadingStatus == LoadingStatus.Success && !itemSet.IsEmpty); } return(false); }
/// <summary> /// 重新加载,先更新变动的数据,再加载 /// </summary> public void ReLoad(string groupKey = "") { Update(false, groupKey); if (!string.IsNullOrEmpty(groupKey)) { groupKey = AbstractEntity.EncodeKeyCode(groupKey); DataContainer.ReLoadItem(groupKey); } else { DataContainer.ReLoad(); } TraceLog.ReleaseWrite("ReLoad {0} end", DataContainer.RootKey); }
/// <summary> /// 尝试从DB中恢复数据 /// </summary> /// <param name="filter"></param> /// <param name="personalId"></param> /// <returns></returns> public bool TryRecoverFromDb(DbDataFilter filter, string personalId = "") { List <T> dataList; if (!string.IsNullOrEmpty(personalId)) { personalId = AbstractEntity.EncodeKeyCode(personalId); } string redisKey = CreateRedisKey(personalId); TransReceiveParam receiveParam = new TransReceiveParam(redisKey); receiveParam.Schema = SchemaTable(); receiveParam.DbFilter = filter; if (DataContainer.TryRecoverFromDb(receiveParam, out dataList)) { return(InitCache(dataList, receiveParam.Schema.PeriodTime, true)); } return(false); }
/// <summary> /// 查找第一个匹配数据 /// </summary> /// <param name="personalId"></param> /// <param name="data"></param> /// <param name="match"></param> /// <returns></returns> public LoadingStatus TryFind(string personalId, Predicate <T> match, out T data) { LoadingStatus loadStatus; T t = default(T); BaseCollection collection; personalId = AbstractEntity.EncodeKeyCode(personalId); if (TryGetGroup(personalId, out collection, out loadStatus)) { collection.Foreach <T>((key, value) => { if (match == null || match(value)) { t = value; return(false); } return(true); }); } data = t; return(loadStatus); }
/// <summary> /// 更新所有的数据 /// </summary> /// <param name="isChange"></param> /// <param name="personalId"></param> public override bool Update(bool isChange, string personalId = null) { personalId = AbstractEntity.EncodeKeyCode(personalId); return(UpdateGroup(isChange, personalId)); }
/// <summary> /// 数据项是否改变 /// </summary> /// <param name="personalId"></param> /// <returns></returns> public bool HasChange(string personalId) { personalId = AbstractEntity.EncodeKeyCode(personalId); return(HasChangeCache(personalId)); }
/// <summary> /// Process synchronized queue of redis /// </summary> /// <param name="sysnWorkingQueueKey"></param> /// <param name="keys"></param> /// <param name="values"></param> private static bool ProcessRedisSyncQueue(string sysnWorkingQueueKey, byte[][] keys, byte[][] values) { bool result = false; try { var redisSyncErrorQueue = new List <byte[][]>(); var entityList = new List <RedisEntityItem>(); var entityRemList = new List <RedisEntityItem>(); var mutilKeyMapList = new List <RedisEntityItem>(); var mutilKeyMapRemList = new List <RedisEntityItem>(); var sqlWaitSyncQueue = new List <KeyValuePair <string, byte[][]> >(); for (int i = 0; i < keys.Length; i++) { byte[] keyBytes = keys[i]; byte[] valueBytes = values[i]; try { string[] queueKey = RedisConnectionPool.ToStringKey(keyBytes).Split('_'); string entityTypeName = RedisConnectionPool.DecodeTypeName(queueKey[0]); string entityParentKey = RedisConnectionPool.GetRedisEntityKeyName(queueKey[0]); byte[] entityKeyBytes = RedisConnectionPool.ToByteKey(queueKey[1]); bool hasMutilKey = false; bool isStoreInDb = true; SchemaTable schema; if (EntitySchemaSet.TryGet(entityTypeName, out schema)) { hasMutilKey = RedisConnectionPool.CurrRedisInfo.ClientVersion >= RedisStorageVersion.HashMutilKeyMap && schema.EntityType.IsSubclassOf(typeof(BaseEntity)) && schema.Keys.Length > 1; isStoreInDb = schema.StorageType.HasFlag(StorageType.WriteOnlyDB) || schema.StorageType.HasFlag(StorageType.ReadWriteDB); } byte[] headBytes; byte[] entityValBytes; int state; int identity; DecodeValueBytes(valueBytes, out headBytes, out entityValBytes, out state, out identity); var entityItem = new RedisEntityItem() { HashId = entityParentKey, UserId = identity, KeyBytes = entityKeyBytes, ValueBytes = entityValBytes, State = state, HasMutilKey = hasMutilKey }; if (entityItem.State == 1) { entityRemList.Add(entityItem); if (hasMutilKey) { mutilKeyMapRemList.Add(entityItem); } } else { entityList.Add(entityItem); if (hasMutilKey) { mutilKeyMapList.Add(entityItem); } } if (_enableWriteToDb && isStoreInDb) { //增加到Sql等待队列 string sqlWaitQueueKey = GetSqlWaitSyncQueueKey(identity); sqlWaitSyncQueue.Add(new KeyValuePair <string, byte[][]>(sqlWaitQueueKey, new[] { keyBytes, headBytes })); } } catch { redisSyncErrorQueue.Add(new[] { keyBytes, valueBytes }); } } var redisErrorKeys = redisSyncErrorQueue.Select(p => p[0]).ToArray(); var redisErrorValues = redisSyncErrorQueue.Select(p => p[1]).ToArray(); var sqlWaitGroups = sqlWaitSyncQueue.GroupBy(p => p.Key); var setGroups = entityList.GroupBy(p => p.HashId); var removeGroups = entityRemList.GroupBy(p => p.HashId); var mutilKeyMapGroups = mutilKeyMapList.GroupBy(p => p.HashId); var mutilKeyMapRemGroups = mutilKeyMapRemList.GroupBy(p => p.HashId); RedisConnectionPool.ProcessPipeline(pipeline => { bool hasPost = false; foreach (var g in setGroups) { var entityKeys = g.Select(p => p.KeyBytes).ToArray(); var entityValues = g.Select(p => p.ValueBytes).ToArray(); pipeline.QueueCommand(client => ((RedisClient)client).HMSet(g.Key, entityKeys, entityValues)); hasPost = true; } foreach (var g in removeGroups) { var keybytes = g.Select(p => p.KeyBytes).ToArray(); pipeline.QueueCommand(client => ((RedisClient)client).HDel(g.Key, keybytes)); hasPost = true; } foreach (var g in mutilKeyMapGroups) { string hashId = g.Key; var subGroup = g.GroupBy(t => t.UserId); foreach (var @group in subGroup) { string firstKey = AbstractEntity.EncodeKeyCode(@group.Key.ToString()); var keybytes = @group.Select(p => p.KeyBytes).ToArray(); pipeline.QueueCommand(client => RedisConnectionPool.SetMutilKeyMap((RedisClient)client, hashId, firstKey, keybytes)); hasPost = true; } } foreach (var g in mutilKeyMapRemGroups) { string hashId = g.Key; var subGroup = g.GroupBy(t => t.UserId); foreach (var @group in subGroup) { string firstKey = AbstractEntity.EncodeKeyCode(@group.Key.ToString()); var keybytes = @group.Select(p => p.KeyBytes).ToArray(); pipeline.QueueCommand(client => RedisConnectionPool.RemoveMutilKeyMap((RedisClient)client, hashId, firstKey, keybytes)); hasPost = true; } } if (redisErrorKeys.Length > 0) { pipeline.QueueCommand(client => ((RedisClient)client).HMSet(RedisSyncErrorQueueKey, redisErrorKeys, redisErrorValues)); hasPost = true; } foreach (var g in sqlWaitGroups) { var sqlWaitKeys = g.Select(p => p.Value[0]).ToArray(); var sqlWaitValues = g.Select(p => p.Value[1]).ToArray(); pipeline.QueueCommand(client => ((RedisClient)client).HMSet(g.Key, sqlWaitKeys, sqlWaitValues)); hasPost = true; } if (hasPost) { pipeline.Flush(); } result = redisErrorKeys.Length == 0; }); } catch (Exception ex) { TraceLog.WriteError("DoProcessRedisSyncQueue error:{0}", ex); try { RedisConnectionPool.Process(client => client.HMSet(RedisSyncErrorQueueKey, keys, values)); } catch (Exception er) { TraceLog.WriteError("Put RedisSyncErrorQueue error:{0}", er); } } return(result); }
/// <summary> /// Contain key of memory. /// </summary> /// <param name="personalId"></param> /// <returns></returns> public bool ContainKey(string personalId) { personalId = AbstractEntity.EncodeKeyCode(personalId); return(ContainGroupKey(personalId)); }
/// <summary> /// /// </summary> /// <param name="personalId"></param> /// <param name="isAutoLoad"></param> /// <returns></returns> public IEnumerable <T> TakeOrLoad(string personalId, bool isAutoLoad = true) { personalId = AbstractEntity.EncodeKeyCode(personalId); return(DataContainer.TakeOrLoadGroup(personalId, isAutoLoad)); }
/// <summary> /// 更新自已的数据 /// </summary> /// <param name="personalId"></param> public void UpdateSelf(string personalId) { personalId = AbstractEntity.EncodeKeyCode(personalId); UpdateGroup(true, personalId); }