//==============================================================
// Copyright (C) 2020 Inc. All rights reserved.
//
//==============================================================
// Create by 种道洋 at 2020/4/9 9:41:02.
// Version 1.0
// 种道洋
//==============================================================
using Cdy.Tag;
using DBRuntime.His;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Diagnostics;
using System.Threading;
namespace Cdy.Tag
{
///
///
///
public class CompressMemory2: MarshalMemoryBlock
{
#region ... Variables ...
private DateTime mCurrentTime;
private IHisEngine2 mHisTagService;
private Dictionary mCompressCach = new Dictionary();
private Dictionary dtmp = new Dictionary();
private List mTagIds=new List();
private bool mIsRunning=false;
private Queue mMemoryCach = new Queue();
#endregion ...Variables...
#region ... Events ...
#endregion ...Events...
#region ... Constructor...
///
///
///
public CompressMemory2():base()
{
mHisTagService = ServiceLocator.Locator.Resolve();
}
///
///
///
///
public CompressMemory2(long size):base(size)
{
}
#endregion ...Constructor...
#region ... Properties ...
///
///
///
public int Id { get; set; }
///
///
///
public static int TagCountPerMemory { get; set; }
///
///
///
public int HeadSize
{
get
{
return 8 + TagCountPerMemory * 8;
}
}
/////
///// 变量内存地址缓存
///// Tuple 每项的含义:起始地址,值地址偏移,质量地址偏移,数据大小
/////
//public Dictionary TagAddress
//{
// get
// {
// return mTagAddress;
// }
// set
// {
// if (mTagAddress != value)
// {
// mTagAddress = value;
// }
// }
//}
///
///
///
public DateTime CurrentTime
{
get
{
return mCurrentTime;
}
set
{
if (mCurrentTime != value)
{
mCurrentTime = value;
}
}
}
///
///
///
public DateTime EndTime { get; set; }
#endregion ...Properties...
#region ... Methods ...
///
///
///
public void RequestManualToCompress()
{
lock (mMemoryCach)
{
mIsRunning = true;
while (mMemoryCach.Count > 0)
{
RequestManualToCompress(mMemoryCach.Dequeue());
}
mIsRunning = false;
}
}
///
///
///
///
public void AddRequestManualToCompress(ManualHisDataMemoryBlock data)
{
mMemoryCach.Enqueue(data);
}
///
///
///
///
private void RequestManualToCompress(ManualHisDataMemoryBlock data)
{
int datasize = 0;
var cdata = CompressMemory(data, out datasize);
cdata.MakeMemoryBusy();
ServiceLocator.Locator.Resolve().ManualRequestToSeriseFile(data.Id, data.Time,data.EndTime, cdata, datasize);
data.MakeMemoryNoBusy();
ManualHisDataMemoryBlockPool.Pool.Release(data);
}
///
///
///
///
public void Init(HisDataMemoryBlockCollection sourceM)
{
mTagIds.Clear();
long lsize = 0;
foreach (var vv in sourceM.TagAddress.Where(e => e.Key >= Id * TagCountPerMemory && e.Key < (Id + 1) * TagCountPerMemory))
{
mTagIds.Add(vv.Key);
dtmp.Add(vv.Key, 0);
var cpt = mHisTagService.GetHisTag(vv.Key).CompressType;
if (!mCompressCach.ContainsKey(cpt))
{
mCompressCach.Add(cpt, CompressUnitManager2.Manager.GetCompressQuick(cpt).Clone());
}
lsize += vv.Value.Length;
}
this.ReAlloc(HeadSize + (long)(lsize*1.2));
this.Clear();
}
///
///
///
public void ReInit(HisDataMemoryBlockCollection sourceM)
{
mTagIds.Clear();
long lsize = 0;
foreach (var vv in sourceM.TagAddress.Where(e => e.Key >= Id * TagCountPerMemory && e.Key < (Id + 1) * TagCountPerMemory))
{
mTagIds.Add(vv.Key);
if (!dtmp.ContainsKey(vv.Key))
dtmp.Add(vv.Key, 0);
var cpt = mHisTagService.GetHisTag(vv.Key).CompressType;
if (!mCompressCach.ContainsKey(cpt))
{
mCompressCach.Add(cpt, CompressUnitManager2.Manager.GetCompressQuick(cpt).Clone());
}
lsize += vv.Value.Length;
}
this.Resize(HeadSize + lsize);
}
///
/// 执行压缩
///
public void Compress(HisDataMemoryBlockCollection source)
{
lock (mMemoryCach)
{
/*
内存结构:Head+数据指针区域+数据区
Head:数据区大小(4)+变量数量(4)
数据区指针:[ID(4) + address(4)]
数据区:[data block]
*/
mIsRunning = true;
try
{
Stopwatch sw = new Stopwatch();
sw.Start();
//CheckTagAddress(source);
long datasize = 0;
int headOffset = 4 + 4;
long Offset = headOffset + mTagIds.Count * 8;
this.MakeMemoryBusy();
long ltmp1 = sw.ElapsedMilliseconds;
//更新数据区域
foreach (var vv in mTagIds)
{
var val = source.TagAddress[vv];
if (val != null)
{
var size = CompressBlockMemory(val, Offset, val.QualityAddress, val.Length, vv);
if (dtmp.ContainsKey(vv))
dtmp[vv] = Offset;
Offset += size;
datasize += size;
}
else
{
dtmp[vv] = 0;
}
}
//更新指针区域
this.WriteInt(0, (int)datasize);//写入整体数据大小
this.Write((int)mTagIds.Count); //写入变量个数
long ltmp2 = sw.ElapsedMilliseconds;
//写入变量、数据区对应的索引
int count = 0;
foreach (var vv in dtmp)
{
this.WriteInt(headOffset + count, (int)vv.Key);
this.WriteInt(headOffset + count + 4, (int)vv.Value);
count += 8;
}
long ltmp3 = sw.ElapsedMilliseconds;
ServiceLocator.Locator.Resolve().RequestToSeriseFile(this);
sw.Stop();
LoggerService.Service.Info("CompressEnginer", Id + "压缩完成 耗时:" + sw.ElapsedMilliseconds + " ltmp1:" + ltmp1 + " ltmp2:" + (ltmp2 - ltmp1) + " ltmp3:" + (ltmp3 - ltmp2) + " CPU Id:" + ThreadHelper.GetCurrentProcessorNumber(), ConsoleColor.Blue);
}
catch (Exception ex)
{
LoggerService.Service.Erro("CompressEnginer", ex.StackTrace + " " + ex.Message);
}
mIsRunning = false;
}
}
///
///
///
///
///
///
///
///
///
private long CompressBlockMemory(HisDataMemoryBlock mSourceMemory, long targetPosition,long qulityOffset, long len, int id)
{
//var qulityoffset = mSourceMemory.ReadInt(addr);
// var id = mSourceMemory.ReadInt(addr + 4);
var histag = mHisTagService.GetHisTag(id);
if (histag == null) return 0;
var qulityoffset = qulityOffset;
var comtype = histag.CompressType;//压缩类型
// this.CheckAndResize(targetPosition + len);
//写入压缩类型
this.WriteByte(targetPosition + 4, (byte)comtype);
var tp = mCompressCach[comtype];
if (tp != null)
{
tp.QulityOffset = (int)qulityoffset;
tp.TagType = histag.TagType;
tp.RecordType = histag.Type;
tp.StartTime = mCurrentTime;
tp.Parameters = histag.Parameters;
tp.Precision = histag.Precision;
tp.TimeTick = 100;
var size = tp.Compress(mSourceMemory, 0, this, targetPosition + 5, len) + 1;
this.WriteInt(targetPosition, (int)size);
//this.Dump();
return size + 5;
}
return 0;
}
///
///
///
///
///
private MarshalMemoryBlock CompressMemory(ManualHisDataMemoryBlock data,out int datasize)
{
MarshalMemoryBlock block = MarshalMemoryBlockPool.Pool.Get(data.Length * 2);
var histag = mHisTagService.GetHisTag(data.Id);
if (histag == null)
{
datasize = 0;
return null;
}
var qulityoffset = data.QualityAddress;
var comtype = histag.CompressType;//压缩类型
block.WriteByte(4, (byte)comtype);
var tp = mCompressCach[comtype];
if (tp != null)
{
tp.QulityOffset = (int)qulityoffset;
tp.TagType = histag.TagType;
tp.RecordType = histag.Type;
tp.StartTime = data.Time;
tp.Parameters = histag.Parameters;
tp.Precision = histag.Precision;
tp.TimeTick = data.TimeUnit;
var size = tp.Compress(data, 0, block, 5, data.Length) + 1;
block.WriteInt(0, (int)size);
datasize = (int)(size + 5);
}
else
{
datasize = 0;
}
return block;
}
///
///
///
public override void Dispose()
{
while (mIsRunning) Thread.Sleep(1);
mHisTagService = null;
mTagIds.Clear();
mTagIds = null;
//mIsDisposed = true;
base.Dispose();
}
#endregion ...Methods...
#region ... Interfaces ...
#endregion ...Interfaces...
}
}