/// <summary> /// 获取当前数据 /// </summary> /// <param name="key">关键字</param> /// <param name="isLive">设置为活动数据</param> /// <returns></returns> public valueType Get(ref keyType key, bool isLive = false) { if (current == null) { currentKey = key; if (!datas.TryGetValue(key, out current)) { datas.Add(key, current = new LiveCount(create(ref key), isLive)); if (datas.Count > maxDataCount && freeData.Count != 0) { keyType removeKey = freeData.UnsafePopNode().Key; datas.Remove(removeKey); LiveCount removeValue; freeData.Remove(ref removeKey, out removeValue); } if (!isLive) { freeData.Set(ref key, current); } } } else if (isLive) { setLive(); } return(current.Value); }
/// <summary> /// 设置域名转换IP地址 /// </summary> /// <param name="key">域名</param> /// <param name="ipAddress">IP地址</param> private static void setDomainIp(HashBytes key, ref DomainIPAddress ipAddress) { Monitor.Enter(domainIpLock); try { domainIps.Set(ref key, ipAddress); if (domainIps.Count == DomainIPAddressConfig.Default.CacheCount) { domainIps.UnsafePopNode(); } } finally { Monitor.Exit(domainIpLock); } }
/// <summary> /// 日志流数据 /// </summary> /// <param name="data"></param> private void onLog(AutoCSer.Net.TcpServer.ReturnValue <Log <valueType, modelType> .Data> data) { if (isError == 0) { if (data.Type == Net.TcpServer.ReturnType.Success) { try { valueType value = data.Value.Value.Value; RandomKey <keyType> key = getKey(data.Value.Value.Value); KeyValue <valueType, EventWaitHandle> queueValue; switch (data.Value.Type) { case LogType.Insert: Monitor.Enter(logLock); if (queue.TryGetOnly(key, out queueValue)) { queue.SetOnly(key, new KeyValue <valueType, EventWaitHandle>(value, null)); Monitor.Exit(logLock); } else { try { queue.Set(ref key, new KeyValue <valueType, EventWaitHandle>(value, null)); if (queue.Count > maxCount) { queue.UnsafePopNode(); } } finally { Monitor.Exit(logLock); } } return; case LogType.Update: Monitor.Enter(logLock); if (queue.TryGetOnly(key, out queueValue)) { if (queueValue.Value == null) { try { AutoCSer.MemberCopy.Copyer <modelType> .Copy(queueValue.Key, value, data.Value.Value.MemberMap); } finally { Monitor.Exit(logLock); } if (data.Value.Value.MemberMap == null && !isErrorMemberMap) { isErrorMemberMap = true; log.add(AutoCSer.Log.LogType.Warn, "客户端缓存数据缺少成员位图信息 " + typeof(valueType).fullName()); } return; } queue.Remove(ref key, out queueValue); } Monitor.Exit(logLock); MemberMapValueLinkPool <valueType> .PushNotNull(value); return; case LogType.Delete: MemberMapValueLinkPool <valueType> .PushNotNull(value); Monitor.Enter(logLock); queue.Remove(ref key, out queueValue); Monitor.Exit(logLock); return; } } catch (Exception error) { log.add(AutoCSer.Log.LogType.Error, error); } } this.error(); } }
/// <summary> /// 日志写入 /// </summary> private void output() { DebugInfo value = null; FileStreamWriter fileStream; do { while (System.Threading.Interlocked.CompareExchange(ref debugLock, 1, 0) != 0) { AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.FileLogExchangeDebug); } if (newDebugs.IsEmpty) { System.Threading.Interlocked.Exchange(ref debugLock, 0); return; } debugs.Exchange(ref newDebugs); System.Threading.Interlocked.Exchange(ref debugLock, 0); do { try { while ((value = debugs.PopOnly()) != null) { switch (value.CacheType) { case CacheType.Queue: HashString cacheKey = value.ToString(); if (cache.Get(ref cacheKey, false)) { fileStream = null; } else { cache.UnsafeAdd(ref cacheKey, true); if (cache.Count > maxCacheCount) { cache.UnsafePopNode(); } fileStream = this.fileStream; } break; case CacheType.Last: HashString key = value.ToString(); if (key.Equals(ref lastCache)) { fileStream = null; } else { lastCache = key; fileStream = this.fileStream; } break; default: fileStream = this.fileStream; break; } if (fileStream != null) { if (value.Type == LogType.Flush) { fileStream.Flush(); } else { string log = @" " + Date.NowTime.Now.toString() + " : " + value.ToString() + @" "; #if XAMARIN Trace.Console(log); if (fileStream.WriteNotEmpty(log) != -1 && (value.Type & LogType.Flush) != 0) { fileStream.Flush(); } #else if (fileStream.WriteNotEmpty(log) >= MaxSize && MaxSize > 0) { moveBak(); } else if ((value.Type & LogType.Flush) != 0) { fileStream.Flush(); } #endif } } pulseWait(value); } goto END; } catch { pulseWait(value); CatchCount.Add(CatchCount.Type.Log_Output); } }while (true); END: debugs.SetHeaderNextNull(); }while (true); }