/// <summary> /// 添加索引 /// </summary> /// <param name="index"></param> /// <returns></returns> public bool AddIndex(ICacheIndex index) { lock (_indexs) { if (_indexDiction.ContainsKey(index.IndexName)) { CacheLog.LogError(string.Format("尝试添加重复的索引【{0}】{1},表【{2}】", index.IndexName, index.IndexType, this.TableName)); throw new Exception(string.Format("索引名称重复:{0}", index.IndexName)); } _indexDiction[index.IndexName] = index; _indexs.Add(index); if (index.IndexType == IndexType.唯一索引) { if (_uniqueIndex == null) { _uniqueIndex = index; } else { CacheLog.LogError(string.Format("尝试重复添加唯一索引【{0}】(原{1}),表【{2}】", index.IndexName, _uniqueIndex.IndexName, this.TableName)); throw new Exception(string.Format("唯一索引已存在:{0},重复设置值:{1}", _uniqueIndex.IndexName, index.IndexName)); } } DataBlock block = new DataBlock(index, _uniqueIndex); _dataRegion.Add(index.IndexName, block); } return(true); }
/// <summary> /// 添加数据 /// </summary> /// <param name="key"></param> /// <param name="item"></param> /// <returns></returns> public ICacheItem Add(ICacheItem item) { try { if (item == null) { return(null); } CheckUniqueIndex(); lock (_tableLock) { foreach (ICacheIndex index in _indexs) { _dataRegion[index.IndexName].Add(item); //TODO: 此处如果有一个索引失败,都要回滚 } return(item); } } catch (Exception ex) { CacheLog.LogError(string.Format("向表添加数据失败:{0}, 表【{1}】;StackTrace:{2}", ex.Message, TableName, ex.StackTrace != null ? ex.StackTrace : "")); throw ex; } }
/// <summary> /// 更新数据 /// 不存在时不更新 /// </summary> /// <param name="item"></param> /// <returns></returns> public ICacheItem Update(ICacheItem item) { try { if (item == null) { return(null); } CheckUniqueIndex(); string uniqueKey = _uniqueIndex.GetIndexKey(item); List <ICacheItem> datas = Get(uniqueKey); if (datas.Count <= 0) { return(null); } item.Copy(datas[0]); return(datas[0]); } catch (Exception ex) { CacheLog.LogError(string.Format("更新表数据失败:{0}, 表【{1}】;StackTrace:{2}", ex.Message, TableName, ex.StackTrace != null ? ex.StackTrace : "")); throw ex; } }
/// <summary> /// 唯一索引检查 /// </summary> private void CheckUniqueIndex() { if (_uniqueIndex == null) { string errorInfo = string.Format("缓存表【{0}】主键不存在错误", TableName); CacheLog.LogError(errorInfo); throw new Exception(errorInfo); } }
/// <summary> /// 获取缓存表 /// </summary> /// <typeparam name="TCacheTableType"></typeparam> /// <returns></returns> public TCacheTable Get <TCacheTable>() where TCacheTable : CacheTable { int tableHash = typeof(TCacheTable).GetHashCode(); if (!_cacheTables.ContainsKey(tableHash)) { CacheLog.LogError(string.Format("尝试访问不存在的表【{0}】", typeof(TCacheTable))); return(null); } return(_cacheTables[tableHash] as TCacheTable); }
/// <summary> /// 根据索引获取缓存 /// 不指定索引名称,则按照唯一索引 /// 缓存不存在,则增加,item为空时,增加一个无效的占位空值 /// </summary> /// <param name="key"></param> /// <param name="item">不存在时添加值</param> /// <param name="indexName"></param> /// <returns></returns> public List <ICacheItem> GetOrAdd(string key, ICacheItem item = null, string indexName = "") { try { List <ICacheItem> datas = Get(key, indexName); if (datas.Count <= 0 && item != null) { Add(item); } return(datas); } catch (Exception ex) { CacheLog.LogError(string.Format("向表查询添加数据失败:{0}, 表【{1}】;StackTrace:{2}", ex.Message, TableName, ex.StackTrace != null? ex.StackTrace:"")); throw ex; } }
/// <summary> /// 添加缓存项 /// 索引重复,会抛出异常 /// </summary> /// <param name="item"></param> /// <returns></returns> public bool Add(ICacheItem item) { string blockKey = _index.GetIndexKey(item); string uniqueKey = _uniqueIndex.GetIndexKey(item); try { _blockLock.EnterUpgradeableReadLock(); if (_uniqueBlock.ContainsKey(uniqueKey)) { throw new Exception(string.Format("索引重复,数据已存在:唯一索引:{0},区块索引:{1}", uniqueKey, blockKey)); } try { _blockLock.EnterWriteLock(); if (!_block.ContainsKey(blockKey)) { _block.Add(blockKey, new List <ICacheItem>()); } _block[blockKey].Add(item); _uniqueBlock.Add(uniqueKey, item); _datas.Add(item); CacheLog.LogDebug(string.Format("添加数据:{0}", item.ToString())); } catch (Exception ex) { throw ex; } finally { _blockLock.ExitWriteLock(); } } catch (Exception ex) { throw ex; } finally { _blockLock.ExitUpgradeableReadLock(); } return(true); }
/// <summary> /// 清空表数据 /// </summary> public void Clear() { try { CheckUniqueIndex(); lock (_tableLock) { foreach (ICacheIndex index in _indexs) { _dataRegion[index.IndexName].Clear(); //TODO: 此处如果有一个索引失败,都要回滚 } } } catch (Exception ex) { CacheLog.LogError(string.Format("执行清表操作失败:{0}, 表【{1}】;StackTrace:{2}", ex.Message, TableName, ex.StackTrace != null ? ex.StackTrace : "")); throw ex; } }
/// <summary> /// 注册缓存表 /// </summary> /// <typeparam name="TCacheItem"></typeparam> /// <param name="iTable"></param> /// <param name="table"></param> public void Register <TCacheTable>() //where ITCacheTable: ICacheTable<ICacheItem> where TCacheTable : CacheTable, new() { int tableHash = typeof(TCacheTable).GetHashCode(); if (_cacheTables.ContainsKey(tableHash)) { CacheLog.LogError(string.Format("表已存在【{0}】", typeof(TCacheTable))); return; } lock (tableLock) { if (_cacheTables.ContainsKey(tableHash)) { CacheLog.LogError(string.Format("表已存在【{0}】", typeof(TCacheTable))); return; } _cacheTables[tableHash] = new TCacheTable(); } }
/// <summary> /// 根据索引获取缓存 /// 不指定索引名称,则按照唯一索引 /// </summary> /// <param name="key">主键</param> /// <param name="indexName">索引名称</param> /// <returns></returns> public List <ICacheItem> Get(string key = "", string indexName = "") { try { CheckUniqueIndex(); if (string.IsNullOrWhiteSpace(indexName)) { indexName = _uniqueIndex.IndexName; } List <ICacheItem> datas = new List <ICacheItem>(); if (!_dataRegion.ContainsKey(indexName)) { return(datas); } datas = _dataRegion[indexName].Get(key); return(datas); } catch (Exception ex) { CacheLog.LogError(string.Format("查询表数据失败:{0}, 表【{1}】;StackTrace:{2}", ex.Message, TableName, ex.StackTrace != null ? ex.StackTrace : "")); throw ex; } }