提交 d729b194 编写于 作者: cdy816's avatar cdy816

内存中查询数据

上级 28dd7768
//==============================================================
// Copyright (C) 2020 Inc. All rights reserved.
//
//==============================================================
// Create by 种道洋 at 2020/10/12 10:06:58.
// Version 1.0
// 种道洋
//==============================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Cdy.Tag
{
/// <summary>
///
/// </summary>
public class DateTimeSpan
{
/// <summary>
///
/// </summary>
public static DateTimeSpan Empty = new DateTimeSpan() { Start = DateTime.MinValue, End = DateTime.MinValue };
/// <summary>
///
/// </summary>
public DateTime Start { get; set; }
/// <summary>
///
/// </summary>
public DateTime End { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return Start == DateTime.MinValue && End == DateTime.MinValue;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool IsZore()
{
return (End - Start).TotalSeconds == 0;
}
/// <summary>
///
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public DateTimeSpan Cross(DateTimeSpan target)
{
DateTime stime = Max(target.Start, this.Start);
DateTime etime = Min(target.End, this.End);
if (etime < stime)
{
return Empty;
}
else
{
return new DateTimeSpan() { Start = stime, End = etime };
}
}
/// <summary>
///
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
public bool Contains(DateTime time)
{
return time >= Start & time < End;
}
/// <summary>
///
/// </summary>
/// <param name="time1"></param>
/// <param name="time2"></param>
/// <returns></returns>
public DateTime Min(DateTime time1, DateTime time2)
{
return time1 <= time2 ? time1 : time2;
}
/// <summary>
///
/// </summary>
/// <param name="time1"></param>
/// <param name="time2"></param>
/// <returns></returns>
public DateTime Max(DateTime time1, DateTime time2)
{
return time1 >= time2 ? time1 : time2;
}
}
}
......@@ -66,6 +66,12 @@ namespace Cdy.Tag
/// <returns></returns>
public abstract bool OpenFile(string filename);
/// <summary>
///
/// </summary>
/// <returns></returns>
public abstract bool IsOpened();
/// <summary>
///
/// </summary>
......
......@@ -151,117 +151,5 @@ namespace Cdy.Tag
/// <returns></returns>
HisQueryResult<T> ReadAllValue<T>(int id, DateTime startTime, DateTime endTime);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<bool> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<byte> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<short> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<ushort> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<int> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<uint> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<long> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<ulong> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<float> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<double> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<DateTime> result);
///// <summary>
/////
///// </summary>
///// <param name="id"></param>
///// <param name="startTime"></param>
///// <param name="endTime"></param>
///// <param name="result"></param>
//void ReadAllValue(int id, DateTime startTime, DateTime endTime, HisQueryResult<string> result);
}
}
//==============================================================
// Copyright (C) 2020 Inc. All rights reserved.
//
//==============================================================
// Create by 种道洋 at 2020/10/12 9:12:46.
// Version 1.0
// 种道洋
//==============================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Cdy.Tag
{
/// <summary>
/// 从内存中查询数据
/// </summary>
public interface IHisQueryFromMemory
{
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="time"></param>
/// <returns></returns>
bool CheckTime(long id, DateTime time);
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
DateTime GetStartMemoryTime(long id);
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="times"></param>
/// <param name="type"></param>
/// <param name="result"></param>
void ReadValue<T>(int id, List<DateTime> times, QueryValueMatchType type, HisQueryResult<T> result);
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="result"></param>
void ReadAllValue<T>(int id, DateTime startTime, DateTime endTime, HisQueryResult<T> result);
}
}
......@@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Text;
......@@ -39,6 +40,13 @@ namespace DBGrpcApiDemo
private int mPort = 14333;
private ICommand mSetTagValueCommand;
private ICommand mQueryHisDataCommand;
private DateTime mStartTime = DateTime.Now.Date;
private DateTime mEndTime;
#endregion ...Variables...
#region ... Events ...
......@@ -52,6 +60,7 @@ namespace DBGrpcApiDemo
public MainViewModel()
{
Init();
mEndTime = mStartTime.AddDays(1);
}
#endregion ...Constructor...
......@@ -211,6 +220,66 @@ namespace DBGrpcApiDemo
}
}
/// <summary>
///
/// </summary>
public DateTime StartTime
{
get
{
return mStartTime;
}
set
{
if (mStartTime != value)
{
mStartTime = value;
OnPropertyChanged("StartTime");
}
}
}
/// <summary>
///
/// </summary>
public DateTime EndTime
{
get
{
return mEndTime;
}
set
{
if (mEndTime != value)
{
mEndTime = value;
OnPropertyChanged("EndTime");
}
}
}
public ICommand QueryHisDataCommand
{
get
{
if (mQueryHisDataCommand == null)
{
mQueryHisDataCommand = new RelayCommand(() =>
{
var vals = clinet.ReadAllHisValue(new List<string> { "tag2" }, StartTime, EndTime);
if (vals != null&&vals.Count>0)
{
MessageBox.Show("读取历史数据个数:" + vals.First().Value.Count);
}
});
}
return mQueryHisDataCommand;
}
}
#endregion ...Properties...
#region ... Methods ...
......
......@@ -9,8 +9,8 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="382*"/>
<RowDefinition Height="32"/>
<RowDefinition Height="*"/>
<RowDefinition Height="64"/>
</Grid.RowDefinitions>
<Label Content="Server:" HorizontalAlignment="Left" Margin="11,0,0,0" VerticalAlignment="Center"/>
<TextBox x:Name="ServerIp" HorizontalAlignment="Left" Margin="67,0,0,0" Text="{Binding Ip,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" TextWrapping="Wrap" VerticalAlignment="Center" Width="196"/>
......@@ -32,11 +32,16 @@
</DataGrid.Columns>
</DataGrid>
<Label Content="变量ID:" HorizontalAlignment="Left" Margin="10,0,0,0" Grid.Row="2" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Margin="70,0,0,0" Grid.Row="2" Text="{Binding Id,Mode=TwoWay}" TextWrapping="Wrap" VerticalAlignment="Center" Width="100"/>
<TextBox HorizontalAlignment="Left" Margin="259,0,0,0" Grid.Row="2" Text="{Binding Value,Mode=TwoWay}" TextWrapping="Wrap" VerticalAlignment="Center" Width="100"/>
<Button Content="变量下发" HorizontalAlignment="Left" Margin="398,0,0,0" Grid.Row="2" VerticalAlignment="Center" Width="76" Command="{Binding SetTagValueCommand}"/>
<Label Content="变量值:" HorizontalAlignment="Left" Margin="206,0,0,0" Grid.Row="2" VerticalAlignment="Center"/>
<Label Content="变量ID:" HorizontalAlignment="Left" Margin="10,4,0,0" Grid.Row="2" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Margin="70,9,0,0" Grid.Row="2" Text="{Binding Id,Mode=TwoWay}" TextWrapping="Wrap" VerticalAlignment="Top" Width="100"/>
<TextBox HorizontalAlignment="Left" Margin="282,9,0,0" Grid.Row="2" Text="{Binding Value,Mode=TwoWay}" TextWrapping="Wrap" VerticalAlignment="Top" Width="100"/>
<Button Content="变量下发" HorizontalAlignment="Left" Margin="458,8,0,0" Grid.Row="2" VerticalAlignment="Top" Width="76" Command="{Binding SetTagValueCommand}"/>
<Label Content="变量值:" HorizontalAlignment="Left" Margin="229,5,0,0" Grid.Row="2" VerticalAlignment="Top"/>
<Label Content="开始时间:" HorizontalAlignment="Left" Margin="4,33,0,0" Grid.Row="2" VerticalAlignment="Top"/>
<DatePicker SelectedDate="{Binding StartTime,Mode=TwoWay}" HorizontalAlignment="Left" Margin="70,35,0,0" Grid.Row="2" VerticalAlignment="Top" Width="132"/>
<Button x:Name="hisqB" Content="读取历史" HorizontalAlignment="Left" Margin="458,37,0,0" Grid.Row="2" VerticalAlignment="Top" Width="76" Command="{Binding QueryHisDataCommand}"/>
<Label Content="结束时间:" HorizontalAlignment="Left" Margin="211,33,0,0" Grid.Row="2" VerticalAlignment="Top"/>
<DatePicker SelectedDate="{Binding EndTime,Mode=TwoWay}" HorizontalAlignment="Left" Margin="277,35,0,0" Grid.Row="2" VerticalAlignment="Top" Width="132"/>
</Grid>
</Window>
......@@ -65,7 +65,7 @@ namespace Cdy.Tag
private ManualResetEvent mResetEvent = new ManualResetEvent(false);
private bool mIsClosed = false;
private Dictionary<string, WatcherChangeTypes> mFileCach = new Dictionary<string, WatcherChangeTypes>();
private Dictionary<string, WatcherChangeTypes> mLogFileCach = new Dictionary<string, WatcherChangeTypes>();
private Dictionary<string, WatcherChangeTypes> mHisFileCach = new Dictionary<string, WatcherChangeTypes>();
......@@ -160,6 +160,9 @@ namespace Cdy.Tag
hisDataWatcher.EnableRaisingEvents = true;
}
//只有在不支持内存查询的情况,才需要监视日志文件
if (ServiceLocator.Locator.Resolve<IHisQueryFromMemory>() != null)
{
string logpath = GetPrimaryLogDataPath();
ScanLogFile(logpath);
if (System.IO.Directory.Exists(logpath))
......@@ -168,6 +171,7 @@ namespace Cdy.Tag
logDataWatcher.Changed += LogDataWatcher_Changed;
logDataWatcher.EnableRaisingEvents = true;
}
}
foreach (var vv in this.mTimeFileMaps)
{
......@@ -222,13 +226,13 @@ namespace Cdy.Tag
mResetCount++;
}
if(mFileCach.Count>0)
if(mLogFileCach.Count>0)
{
lock(mLocker)
{
ltmp = mFileCach.ToList();
mFileCach.Clear();
ltmp = mLogFileCach.ToList();
mLogFileCach.Clear();
}
foreach(var vv in ltmp)
......@@ -294,9 +298,9 @@ namespace Cdy.Tag
{
lock (mLocker)
{
if (!mFileCach.ContainsKey(e.FullPath))
if (!mLogFileCach.ContainsKey(e.FullPath))
{
mFileCach.Add(e.FullPath, e.ChangeType);
mLogFileCach.Add(e.FullPath, e.ChangeType);
}
}
}
......
......@@ -17,23 +17,24 @@ namespace Cdy.Tag
/// </summary>
public class QuerySerivce: IHisQuery
{
IHisQueryFromMemory mMemoryService;
/// <summary>
///
/// </summary>
public QuerySerivce()
{
mMemoryService = ServiceLocator.Locator.Resolve<IHisQueryFromMemory>() as IHisQueryFromMemory;
}
/// <summary>
///
/// </summary>
/// <param name="databaseName"></param>
public QuerySerivce(string databaseName)
public QuerySerivce(string databaseName) : this()
{
Database = databaseName;
}
public string Database { get; set; }
......@@ -47,6 +48,15 @@ namespace Cdy.Tag
return HisQueryManager.Instance.GetFileManager(Database);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private bool IsCanQueryFromMemory()
{
return mMemoryService != null;
}
/// <summary>
///
/// </summary>
......@@ -57,13 +67,36 @@ namespace Cdy.Tag
/// <param name="result"></param>
public void ReadValue<T>(int id, List<DateTime> times, QueryValueMatchType type, HisQueryResult<T> result)
{
List<DateTime> ltmp = new List<DateTime>();
List<DateTime> mMemoryTimes = new List<DateTime>();
//判断数据是否在内存中
if (IsCanQueryFromMemory())
{
foreach(var vv in times)
{
if(!mMemoryService.CheckTime(id,vv))
{
ltmp.Add(vv);
}
else
{
mMemoryTimes.Add(vv);
}
}
}
else
{
ltmp.AddRange(times);
}
List<DateTime> mLogTimes = new List<DateTime>();
var vfiles = GetFileManager().GetDataFiles(times, mLogTimes, id);
var vfiles = GetFileManager().GetDataFiles(ltmp, mLogTimes, id);
DataFileInfo mPreFile = null;
List<DateTime> mtime = new List<DateTime>();
//从历史文件中读取数据
foreach (var vv in vfiles)
{
if (vv.Value == null)
......@@ -96,9 +129,24 @@ namespace Cdy.Tag
mPreFile.Read<T>(id, mtime, type, result);
}
//从日志文件中读取数据
ReadLogFile(id, mLogTimes, type, result);
//从内存中读取数据
ReadFromMemory(id, mMemoryTimes, type, result);
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="times"></param>
/// <param name="type"></param>
/// <param name="result"></param>
private void ReadFromMemory<T>(int id,List<DateTime> times, QueryValueMatchType type, HisQueryResult<T> result)
{
mMemoryService?.ReadValue(id, times, type, result);
}
/// <summary>
///
......@@ -170,6 +218,19 @@ namespace Cdy.Tag
});
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="starttime"></param>
/// <param name="endTime"></param>
/// <param name="result"></param>
private void ReadAllValueFromMemory<T>(int id,DateTime starttime,DateTime endTime,HisQueryResult<T> result)
{
mMemoryService?.ReadAllValue(id, starttime, endTime, result);
}
/// <summary>
///
/// </summary>
......@@ -182,8 +243,29 @@ namespace Cdy.Tag
{
try
{
DateTime etime = endTime,stime = startTime;
DateTime memoryTime = DateTime.MaxValue;
if(IsCanQueryFromMemory())
{
memoryTime = mMemoryService.GetStartMemoryTime(id);
}
if(startTime>=memoryTime)
{
ReadAllValueFromMemory(id, startTime, endTime, result);
}
else
{
if(endTime>memoryTime)
{
etime = memoryTime;
}
Tuple<DateTime, DateTime> mLogFileTimes;
var vfiles = GetFileManager().GetDataFiles(startTime, endTime, out mLogFileTimes, id);
var vfiles = GetFileManager().GetDataFiles(stime, etime, out mLogFileTimes, id);
//从历史记录中读取数据
vfiles.ForEach(e =>
{
DateTime sstart = e.StartTime > startTime ? e.StartTime : startTime;
......@@ -191,10 +273,20 @@ namespace Cdy.Tag
e.ReadAllValue(id, sstart, eend, result);
});
if (mLogFileTimes.Item1 <mLogFileTimes.Item2)
//从日志文件中读取数据
if (mLogFileTimes.Item1 < mLogFileTimes.Item2)
{
ReadLogFileAllValue(id, mLogFileTimes.Item1, mLogFileTimes.Item2, result);
}
//从内存中读取数据
if(endTime>memoryTime)
{
ReadAllValueFromMemory(id, memoryTime, endTime, result);
}
}
}
catch(Exception ex)
{
......
......@@ -348,86 +348,7 @@ namespace Cdy.Tag
#endregion ...Interfaces...
}
/// <summary>
///
/// </summary>
public class DateTimeSpan
{
/// <summary>
///
/// </summary>
public DateTimeSpan Empty = new DateTimeSpan() { Start = DateTime.MinValue, End = DateTime.MinValue };
/// <summary>
///
/// </summary>
public DateTime Start { get; set; }
/// <summary>
///
/// </summary>
public DateTime End { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return Start == DateTime.MinValue && End == DateTime.MinValue;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool IsZore()
{
return (End - Start).TotalSeconds == 0;
}
/// <summary>
///
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public DateTimeSpan Cross(DateTimeSpan target)
{
DateTime stime = Max(target.Start, this.Start);
DateTime etime = Min(target.End, this.End);
if (etime < stime)
{
return Empty;
}
else
{
return new DateTimeSpan() { Start = stime, End = etime };
}
}
/// <summary>
///
/// </summary>
/// <param name="time1"></param>
/// <param name="time2"></param>
/// <returns></returns>
public DateTime Min(DateTime time1, DateTime time2)
{
return time1 <= time2 ? time1 : time2;
}
/// <summary>
///
/// </summary>
/// <param name="time1"></param>
/// <param name="time2"></param>
/// <returns></returns>
public DateTime Max(DateTime time1, DateTime time2)
{
return time1 >= time2 ? time1 : time2;
}
}
public static class DataFileInfoExtend
......
......@@ -443,6 +443,9 @@ namespace Cdy.Tag
long addroffset = 0;
short len = 0;
int datasize = 0;
if (!datafile.IsOpened()) return;
var aid = datafile.ReadTagIndex(tid,out addroffset,out len);
if(aid!=null)
{
......@@ -658,6 +661,8 @@ namespace Cdy.Tag
long addroffset = 0;
short len = 0;
int datasize = 0;
if (!datafile.IsOpened()) return;
var aid = datafile.ReadTagIndex(tid, out addroffset, out len);
if(aid!=null)
{
......
......@@ -2,7 +2,7 @@
"profiles": {
"DBInRun": {
"commandName": "Executable",
"executablePath": "C:\\Users\\cdy81\\source\\repos\\mars\\Output\\DBInRun.exe"
"executablePath": "C:\\Users\\chongdaoyang\\source\\repos\\mars\\Output\\DBInRun.exe"
}
}
}
\ No newline at end of file
......@@ -300,6 +300,7 @@ namespace Cdy.Tag
mm.Value.Compress(sm);
});
HisDataMemoryQueryService.Service.ClearMemoryTime(sm.CurrentDatetime);
sm.Clear();
sm.MakeMemoryNoBusy();
......
......@@ -194,6 +194,8 @@ namespace Cdy.Tag
cdata.MakeMemoryBusy();
ServiceLocator.Locator.Resolve<IDataSerialize2>().ManualRequestToSeriseFile(cdata);
data.MakeMemoryNoBusy();
HisDataMemoryQueryService.Service.ClearManualMemoryTime(data.Id, data.Time);
ManualHisDataMemoryBlockPool.Pool.Release(data);
}
......
//==============================================================
// Copyright (C) 2020 Inc. All rights reserved.
//
//==============================================================
// Create by 种道洋 at 2020/10/12 9:19:01.
// Version 1.0
// 种道洋
//==============================================================
using Cdy.Tag;
using DotNetty.Common;
using Google.Protobuf.Reflection;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace DBRuntime.His
{
/// <summary>
///
/// </summary>
public class HisDataMemoryQueryService : IHisQueryFromMemory
{
#region ... Variables ...
/// <summary>
///
/// </summary>
public static HisDataMemoryQueryService Service = new HisDataMemoryQueryService();
private Dictionary<long, SortedDictionary<DateTime,ManualTimeSpanMemory>> mManualHisMemorys = new Dictionary<long, SortedDictionary<DateTime, ManualTimeSpanMemory>>();
private SortedDictionary<DateTime, TimeSpanMemory> mHisMemorys = new SortedDictionary<DateTime, TimeSpanMemory>();
#endregion ...Variables...
#region ... Events ...
#endregion ...Events...
#region ... Constructor...
#endregion ...Constructor...
#region ... Properties ...
/// <summary>
///
/// </summary>
public HisEnginer2 HisEnginer { get; set; }
#endregion ...Properties...
#region ... Methods ...
/// <summary>
///
/// </summary>
public void Clear()
{
mHisMemorys.Clear();
mManualHisMemorys.Clear();
}
/// <summary>
///
/// </summary>
/// <param name="time"></param>
/// <param name="endtime"></param>
public void RegistorMemory(DateTime startTime,DateTime endtime, HisDataMemoryBlockCollection memory)
{
lock (mHisMemorys)
{
if (mHisMemorys.ContainsKey(startTime))
{
var vitem = mHisMemorys[startTime];
vitem.End = endtime;
vitem.Memory = memory;
}
else
{
var vitem = new TimeSpanMemory() { Start = startTime, End = endtime, Memory = memory };
mHisMemorys.Add(startTime, vitem);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="startTime"></param>
public void ClearMemoryTime(DateTime startTime)
{
lock (mHisMemorys)
{
if (mHisMemorys.ContainsKey(startTime))
{
mHisMemorys.Remove(startTime);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="memory"></param>
public void RegistorManual(long id,DateTime startTime,DateTime endTime, ManualHisDataMemoryBlock memory)
{
lock (mManualHisMemorys)
{
if (mManualHisMemorys.ContainsKey(id))
{
var vv = mManualHisMemorys[id];
if (!vv.ContainsKey(startTime))
{
vv.Add(startTime, new ManualTimeSpanMemory() { Start = startTime, End = endTime, Memory = memory });
}
else
{
var vitem = vv[startTime];
vitem.End = endTime;
vitem.Memory = memory;
}
}
else
{
SortedDictionary<DateTime, ManualTimeSpanMemory> mms = new SortedDictionary<DateTime, ManualTimeSpanMemory>();
mms.Add(startTime, new ManualTimeSpanMemory() { Start = startTime, End = endTime, Memory = memory });
mManualHisMemorys.Add(id, mms);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="startTime"></param>
public void ClearManualMemoryTime(int id, DateTime startTime)
{
lock (mManualHisMemorys)
{
if (mManualHisMemorys.ContainsKey(id))
{
if (mManualHisMemorys[id].ContainsKey(startTime))
{
mManualHisMemorys[id].Remove(startTime);
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private bool IsManualRecord(long id)
{
if (this.HisEnginer.HisTagManager.HisTags.ContainsKey(id))
{
return HisEnginer.HisTagManager.HisTags[id].Type == RecordType.Manual;
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="time"></param>
public bool CheckTime(long id,DateTime time)
{
if(IsManualRecord(id))
{
lock (mManualHisMemorys)
{
if (mManualHisMemorys.ContainsKey(id))
{
foreach (var vv in mManualHisMemorys[id])
{
if (vv.Value.Contains(time)) return true;
}
}
}
return false;
}
else
{
lock (mHisMemorys)
{
foreach (var vv in mHisMemorys)
{
if (vv.Value.Contains(time)) return true;
}
}
return false;
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <returns></returns>
public DateTime GetStartMemoryTime(long id)
{
if (IsManualRecord(id))
{
lock (mManualHisMemorys)
{
if (mManualHisMemorys.ContainsKey(id))
{
return mManualHisMemorys[id].First().Key;
}
}
return DateTime.MinValue;
}
else
{
lock (mHisMemorys)
{
if (mHisMemorys.Count > 0)
return mHisMemorys.First().Key;
else
{
return DateTime.MinValue;
}
}
}
}
/// <summary>
/// 查询所有值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="result"></param>
public void ReadAllValue<T>(int id, DateTime startTime, DateTime endTime, HisQueryResult<T> result)
{
if (!IsManualRecord(id))
{
KeyValuePair<DateTime, TimeSpanMemory>[] vhh;
lock(mHisMemorys)
vhh = mHisMemorys.ToArray();
foreach(var vv in vhh)
{
var vss = vv.Value.Cross(new DateTimeSpan() { Start = startTime, End = endTime });
if(!vss.IsEmpty())
{
if (!vv.Value.Memory.TagAddress.ContainsKey(id)) break;
var vmm = vv.Value.Memory.TagAddress[id];
var stim = (int)((vss.Start - vv.Value.Memory.CurrentDatetime).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
var etim = (int)((vss.End - vv.Value.Memory.CurrentDatetime).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
var tims = ReadTimer(stim, etim, vmm);
var vals = ReadValueInner<T>(vmm, tims.Keys.ToList(), 0, vmm.ValueAddress);
foreach(var vvk in tims)
{
var time = vv.Value.Memory.CurrentDatetime.AddMilliseconds(vvk.Value * HisEnginer2.MemoryTimeTick);
result.Add(vals[vvk.Key], time, vmm.ReadByte(vvk.Key + vmm.QualityAddress));
}
}
}
}
else
{
KeyValuePair<DateTime, ManualTimeSpanMemory>[] vhh;
lock (mManualHisMemorys)
{
if (!mManualHisMemorys.ContainsKey(id)) return;
vhh = mManualHisMemorys[id].ToArray();
}
foreach (var vv in vhh)
{
var vss = vv.Value.Cross(new DateTimeSpan() { Start = startTime, End = endTime });
if (!vss.IsEmpty())
{
var vmm = vv.Value.Memory;
var stim = (int)((vss.Start - vv.Value.Memory.Time).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
var etim = (int)((vss.End - vv.Value.Memory.Time).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
var tims = ReadTimer2(stim, etim, vmm);
var vals = ReadValueInner<T>(vmm, tims.Keys.ToList(), 0, vmm.ValueAddress);
foreach (var vvk in tims)
{
var time = vv.Value.Memory.Time.AddMilliseconds(vvk.Value * HisEnginer2.MemoryTimeTick);
result.Add(vals[vvk.Key], time, vmm.ReadByte(vvk.Key + vmm.QualityAddress));
}
}
}
}
}
private Dictionary<int, int> ReadTimer(int start, int end, HisDataMemoryBlock block)
{
Dictionary<int, int> re = new Dictionary<int, int>();
bool isStart = false;
var vcount = block.ValueAddress/2;
for (int i = 0; i < vcount; i++)
{
var val = block.ReadShort(i * 2);
if (i != 0 && val == 0) continue;
if (!isStart)
{
if (val >= start)
{
isStart = true;
re.Add(i, val);
}
}
else
{
if (val > end) break;
else
{
re.Add(i, val);
}
}
}
return re;
}
/// <summary>
///
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="block"></param>
/// <returns></returns>
private Dictionary<int, int> ReadTimer2(int start, int end, HisDataMemoryBlock block)
{
Dictionary<int, int> re = new Dictionary<int, int>();
bool isStart = false;
var vcount = block.ValueAddress/4;
for (int i = 0; i < vcount; i++)
{
var val = block.ReadInt(i*4);
if (i != 0 && val == 0) continue;
if (!isStart)
{
if (val >= start)
{
isStart = true;
re.Add(i, val);
}
}
else
{
if (val > end) break;
else
{
re.Add(i, val);
}
}
}
return re;
}
/// <summary>
///
/// </summary>
/// <param name="time"></param>
/// <param name="block"></param>
private Tuple<int,int> ReadTimeToFit(int time,HisDataMemoryBlock block)
{
var vcount = block.ValueAddress/2;
short prev = block.ReadShort(0);
if (prev == time) return new Tuple<int, int>(0, 0);
else if (time < prev) return new Tuple<int, int>(-1, -1);
for(int i=1;i<vcount;i++)
{
var after = block.ReadShort(i * 2);
if(time == after)
{
return new Tuple<int, int>(after, after);
}
else if(time<after)
{
return new Tuple<int, int>(i - 1, i);
}
prev = after;
}
return new Tuple<int, int>(-1, -1);
}
/// <summary>
///
/// </summary>
/// <param name="time"></param>
/// <param name="block"></param>
/// <returns></returns>
private Tuple<int, int> ReadTimeToFit2(int time, HisDataMemoryBlock block)
{
var vcount = block.ValueAddress/4;
int prev = block.ReadInt(0);
if (prev == time) return new Tuple<int, int>(0, 0);
else if (time < prev) return new Tuple<int, int>(-1, -1);
for (int i = 1; i < vcount; i++)
{
var after = block.ReadInt(i * 4);
if (time == after)
{
return new Tuple<int, int>(after, after);
}
else if (time < after)
{
return new Tuple<int, int>(i - 1, i);
}
prev = after;
}
return new Tuple<int, int>(-1, -1);
}
private List<object> ReadValueInner<T>(HisDataMemoryBlock datafile, List<int> valIndex, long offset, long valueaddr)
{
List<object> re = new List<object>();
if (typeof(T) == typeof(bool))
{
foreach (var vv in valIndex)
{
re.Add(Convert.ToBoolean(datafile.ReadByte(offset + valueaddr + vv)));
}
}
else if (typeof(T) == typeof(byte))
{
foreach (var vv in valIndex)
{
re.Add(datafile.ReadByte(offset + valueaddr + vv));
}
}
else if (typeof(T) == typeof(short))
{
foreach (var vv in valIndex)
{
re.Add(datafile.ReadShort(offset + valueaddr + vv * 2));
}
}
else if (typeof(T) == typeof(ushort))
{
foreach (var vv in valIndex)
{
re.Add((ushort)datafile.ReadShort(offset + valueaddr + vv * 2));
}
}
else if (typeof(T) == typeof(int))
{
foreach (var vv in valIndex)
{
re.Add(datafile.ReadInt(offset + valueaddr + vv * 4));
}
}
else if (typeof(T) == typeof(uint))
{
foreach (var vv in valIndex)
{
re.Add((uint)datafile.ReadInt(offset + valueaddr + vv * 4));
}
}
else if (typeof(T) == typeof(long))
{
foreach (var vv in valIndex)
{
re.Add((long)datafile.ReadLong(offset + valueaddr + vv * 8));
}
}
else if (typeof(T) == typeof(ulong))
{
foreach (var vv in valIndex)
{
re.Add((ulong)datafile.ReadLong(offset + valueaddr + vv * 8));
}
}
else if (typeof(T) == typeof(double))
{
foreach (var vv in valIndex)
{
re.Add(datafile.ReadDouble(offset + valueaddr + vv * 8));
}
}
else if (typeof(T) == typeof(float))
{
foreach (var vv in valIndex)
{
re.Add(datafile.ReadFloat(offset + valueaddr + vv * 4));
}
}
else if (typeof(T) == typeof(string))
{
foreach (var vv in valIndex)
{
var str = Encoding.Unicode.GetString(datafile.ReadBytes(offset + valueaddr + vv * Const.StringSize, Const.StringSize));
re.Add(str);
}
}
else if (typeof(T) == typeof(DateTime))
{
foreach (var vv in valIndex)
{
re.Add(datafile.ReadDateTime(offset + valueaddr + vv * 8));
}
}
else if (typeof(T) == typeof(IntPointData))
{
foreach (var vv in valIndex)
{
var x = datafile.ReadInt(offset + valueaddr + vv * 8);
var y = datafile.ReadInt(offset + valueaddr + vv * 8 + 4);
re.Add(new IntPointData() { X = x, Y = y });
}
}
else if (typeof(T) == typeof(UIntPointData))
{
foreach (var vv in valIndex)
{
var x = (uint)datafile.ReadInt(offset + valueaddr + vv * 8);
var y = (uint)datafile.ReadInt(offset + valueaddr + vv * 8 + 4);
re.Add(new UIntPointData() { X = x, Y = y });
}
}
else if (typeof(T) == typeof(LongPointData))
{
foreach (var vv in valIndex)
{
var x = (long)datafile.ReadLong(offset + valueaddr + vv * 16);
var y = (long)datafile.ReadLong(offset + valueaddr + vv * 16 + 8);
re.Add(new LongPointData() { X = x, Y = y });
}
}
else if (typeof(T) == typeof(ULongPointData))
{
foreach (var vv in valIndex)
{
var x = (ulong)datafile.ReadLong(offset + valueaddr + vv * 16);
var y = (ulong)datafile.ReadLong(offset + valueaddr + vv * 16 + 8);
re.Add(new ULongPointData() { X = x, Y = y });
}
}
else if (typeof(T) == typeof(IntPoint3Data))
{
foreach (var vv in valIndex)
{
var x = datafile.ReadInt(offset + valueaddr + vv * 12);
var y = datafile.ReadInt(offset + valueaddr + vv * 12 + 4);
var z = datafile.ReadInt(offset + valueaddr + vv * 12 + 8);
re.Add(new IntPoint3Data() { X = x, Y = y, Z = z });
}
}
else if (typeof(T) == typeof(UIntPoint3Data))
{
foreach (var vv in valIndex)
{
var x = (uint)datafile.ReadInt(offset + valueaddr + vv * 12);
var y = (uint)datafile.ReadInt(offset + valueaddr + vv * 12 + 4);
var z = (uint)datafile.ReadInt(offset + valueaddr + vv * 12 + 8);
re.Add(new UIntPoint3Data() { X = x, Y = y, Z = z });
}
}
else if (typeof(T) == typeof(LongPoint3Data))
{
foreach (var vv in valIndex)
{
var x = (long)datafile.ReadLong(offset + valueaddr + vv * 24);
var y = (long)datafile.ReadLong(offset + valueaddr + vv * 24 + 8);
var z = (long)datafile.ReadLong(offset + valueaddr + vv * 24 + 168);
re.Add(new LongPoint3Data() { X = x, Y = y, Z = z });
}
}
else if (typeof(T) == typeof(ULongPoint3Data))
{
foreach (var vv in valIndex)
{
var x = (ulong)datafile.ReadLong(offset + valueaddr + vv * 24);
var y = (ulong)datafile.ReadLong(offset + valueaddr + vv * 24 + 8);
var z = (ulong)datafile.ReadLong(offset + valueaddr + vv * 24 + 168);
re.Add(new ULongPoint3Data() { X = x, Y = y, Z = z });
}
}
return re;
}
/// <summary>
/// 查询指定时刻的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="times"></param>
/// <param name="type"></param>
/// <param name="result"></param>
public void ReadValue<T>(int id, List<DateTime> times, QueryValueMatchType type, HisQueryResult<T> result)
{
if(!IsManualRecord(id))
{
KeyValuePair<DateTime, TimeSpanMemory>[] vhh;
lock (mHisMemorys)
vhh = mHisMemorys.ToArray();
foreach (var vtime in times)
{
foreach (var vv in vhh)
{
if (vv.Value.Contains(vtime))
{
if (vv.Value.Memory.TagAddress.ContainsKey(id))
{
var tim = (int)((vtime - vv.Value.Memory.CurrentDatetime).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
var vmm = vv.Value.Memory.TagAddress[id];
var timeindx = ReadTimeToFit(tim, vmm);
if (timeindx.Item1 > -1 && timeindx.Item2 > -1)
{
if (timeindx.Item1 == timeindx.Item2)
{
var vals = ReadValueInner<T>(vmm, new List<int>() { timeindx.Item1 }, 0, vmm.ValueAddress);
var qua = vmm.ReadByte(vmm.QualityAddress + timeindx.Item1);
result.Add(vals[0], vtime, qua);
}
else
{
var vals = ReadValueInner<T>(vmm, new List<int>() { timeindx.Item1, timeindx.Item2 }, 0, vmm.ValueAddress);
var qua1 = vmm.ReadByte(vmm.QualityAddress + timeindx.Item1);
var qua2 = vmm.ReadByte(vmm.QualityAddress + timeindx.Item2);
var time1 = vv.Value.Memory.CurrentDatetime.AddMilliseconds(vmm.ReadShort(timeindx.Item1) * HisEnginer2.MemoryTimeTick);
var time2 = vv.Value.Memory.CurrentDatetime.AddMilliseconds(vmm.ReadShort(timeindx.Item2) * HisEnginer2.MemoryTimeTick);
switch (type)
{
case QueryValueMatchType.Previous:
result.Add(vals[0], vtime, qua1);
break;
case QueryValueMatchType.After:
result.Add(vals[1], vtime, qua2);
break;
case QueryValueMatchType.Linear:
if (typeof(T) == typeof(bool) || typeof(T) == typeof(string) || typeof(T) == typeof(DateTime))
{
var ppval = (vtime - time1).TotalMilliseconds;
var ffval = (time2 - vtime).TotalMilliseconds;
if (ppval < ffval)
{
result.Add(vals[0], vtime, qua1);
}
else
{
result.Add(vals[1], vtime, qua2);
}
}
else
{
if (qua1 < 20 && qua2 < 20)
{
if (CheckTypeIsPointData(typeof(T)))
{
result.Add(LinerValue(time1, time2, vtime, vals[0], vals[1]), vtime, 0);
}
else
{
var pval1 = (vtime - time1).TotalMilliseconds;
var tval1 = (time2 - time1).TotalMilliseconds;
var sval1 = (double)vals[0];
var sval2 = (double)vals[1];
var val1 = pval1 / tval1 * (sval2 - sval1) + sval1;
result.Add((object)val1, vtime, 0);
}
}
else if (qua1 < 20)
{
result.Add(vals[0], vtime, qua1);
}
else if (qua2 < 20)
{
result.Add(vals[1], vtime, qua2);
}
else
{
result.Add(default(T), time1, (byte)QualityConst.Null);
}
}
break;
case QueryValueMatchType.Closed:
var pval = (vtime - time1).TotalMilliseconds;
var fval = (time2 - vtime).TotalMilliseconds;
if (pval < fval)
{
result.Add(vals[0], time1, qua1);
}
else
{
result.Add(vals[1], time1, qua2);
}
break;
}
}
}
}
break;
}
}
}
}
else
{
KeyValuePair<DateTime, ManualTimeSpanMemory>[] vhh;
lock (mManualHisMemorys)
{
if (!mManualHisMemorys.ContainsKey(id)) return;
vhh = mManualHisMemorys[id].ToArray();
}
foreach (var vtime in times)
{
foreach (var vv in vhh)
{
if (vv.Value.Contains(vtime))
{
var tim = (int)((vtime - vv.Value.Memory.Time).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
var vmm = vv.Value.Memory;
var timeindx = ReadTimeToFit2(tim, vmm);
if (timeindx.Item1 > -1 && timeindx.Item2 > -1)
{
if (timeindx.Item1 == timeindx.Item2)
{
var vals = ReadValueInner<T>(vmm, new List<int>() { timeindx.Item1 }, 0, vmm.ValueAddress);
var qua = vmm.ReadByte(vmm.QualityAddress + timeindx.Item1);
result.Add(vals[0], vtime, qua);
}
else
{
var vals = ReadValueInner<T>(vmm, new List<int>() { timeindx.Item1, timeindx.Item2 }, 0, vmm.ValueAddress);
var qua1 = vmm.ReadByte(vmm.QualityAddress + timeindx.Item1);
var qua2 = vmm.ReadByte(vmm.QualityAddress + timeindx.Item2);
var time1 = vv.Value.Memory.Time.AddMilliseconds(vmm.ReadInt(timeindx.Item1) * HisEnginer2.MemoryTimeTick);
var time2 = vv.Value.Memory.Time.AddMilliseconds(vmm.ReadInt(timeindx.Item2) * HisEnginer2.MemoryTimeTick);
switch (type)
{
case QueryValueMatchType.Previous:
result.Add(vals[0], vtime, qua1);
break;
case QueryValueMatchType.After:
result.Add(vals[1], vtime, qua2);
break;
case QueryValueMatchType.Linear:
if (typeof(T) == typeof(bool) || typeof(T) == typeof(string) || typeof(T) == typeof(DateTime))
{
var ppval = (vtime - time1).TotalMilliseconds;
var ffval = (time2 - vtime).TotalMilliseconds;
if (ppval < ffval)
{
result.Add(vals[0], vtime, qua1);
}
else
{
result.Add(vals[1], vtime, qua2);
}
}
else
{
if (qua1 < 20 && qua2 < 20)
{
if (CheckTypeIsPointData(typeof(T)))
{
result.Add(LinerValue(time1, time2, vtime, vals[0], vals[1]), vtime, 0);
}
else
{
var pval1 = (vtime - time1).TotalMilliseconds;
var tval1 = (time2 - time1).TotalMilliseconds;
var sval1 = (double)vals[0];
var sval2 = (double)vals[1];
var val1 = pval1 / tval1 * (sval2 - sval1) + sval1;
result.Add((object)val1, vtime, 0);
}
}
else if (qua1 < 20)
{
result.Add(vals[0], vtime, qua1);
}
else if (qua2 < 20)
{
result.Add(vals[1], vtime, qua2);
}
else
{
result.Add(default(T), time1, (byte)QualityConst.Null);
}
}
break;
case QueryValueMatchType.Closed:
var pval = (vtime - time1).TotalMilliseconds;
var fval = (time2 - vtime).TotalMilliseconds;
if (pval < fval)
{
result.Add(vals[0], time1, qua1);
}
else
{
result.Add(vals[1], time1, qua2);
}
break;
}
}
}
}
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static bool CheckTypeIsPointData(Type type)
{
return type == typeof(IntPointData) || type == typeof(UIntPointData) || type == typeof(LongPointData) || type == typeof(ULongPointData) || type == typeof(IntPoint3Data) || type == typeof(UIntPoint3Data) || type == typeof(LongPoint3Data) || type == typeof(ULongPoint3Data);
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="time"></param>
/// <param name="value1"></param>
/// <param name="value2"></param>
/// <returns></returns>
private object LinerValue<T>(DateTime startTime, DateTime endTime, DateTime time, T value1, T value2)
{
var pval1 = (time - startTime).TotalMilliseconds;
var tval1 = (endTime - startTime).TotalMilliseconds;
if (typeof(T) == typeof(IntPointData))
{
var sval1 = (IntPointData)((object)value1);
var sval2 = (IntPointData)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
return new IntPointData((int)val1, (int)val2);
}
else if (typeof(T) == typeof(UIntPointData))
{
var sval1 = (UIntPointData)((object)value1);
var sval2 = (UIntPointData)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
return new UIntPointData((uint)val1, (uint)val2);
}
else if (typeof(T) == typeof(LongPointData))
{
var sval1 = (LongPointData)((object)value1);
var sval2 = (LongPointData)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
return new LongPointData((long)val1, (long)val2);
}
else if (typeof(T) == typeof(ULongPointData))
{
var sval1 = (ULongPointData)((object)value1);
var sval2 = (ULongPointData)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
return new ULongPointData((ulong)val1, (ulong)val2);
}
else if (typeof(T) == typeof(IntPoint3Data))
{
var sval1 = (IntPoint3Data)((object)value1);
var sval2 = (IntPoint3Data)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z);
return new IntPoint3Data((int)val1, (int)val2, (int)val3);
}
else if (typeof(T) == typeof(UIntPoint3Data))
{
var sval1 = (UIntPoint3Data)((object)value1);
var sval2 = (UIntPoint3Data)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z);
return new UIntPoint3Data((uint)val1, (uint)val2, (uint)val3);
}
else if (typeof(T) == typeof(LongPoint3Data))
{
var sval1 = (LongPoint3Data)((object)value1);
var sval2 = (LongPoint3Data)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z);
return new LongPoint3Data((long)val1, (long)val2, (long)val3);
}
else if (typeof(T) == typeof(ULongPoint3Data))
{
var sval1 = (ULongPoint3Data)((object)value1);
var sval2 = (ULongPoint3Data)((object)value2);
var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X);
var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y);
var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z);
return new ULongPoint3Data((ulong)val1, (ulong)val2, (ulong)val3);
}
return default(T);
}
#endregion ...Methods...
#region ... Interfaces ...
#endregion ...Interfaces...
}
/// <summary>
///
/// </summary>
public class ManualTimeSpanMemory : DateTimeSpan
{
/// <summary>
///
/// </summary>
public ManualHisDataMemoryBlock Memory { get; set; }
}
/// <summary>
///
/// </summary>
public class TimeSpanMemory : DateTimeSpan
{
#region ... Variables ...
#endregion ...Variables...
#region ... Events ...
#endregion ...Events...
#region ... Constructor...
#endregion ...Constructor...
#region ... Properties ...
/// <summary>
///
/// </summary>
public HisDataMemoryBlockCollection Memory { get; set; }
#endregion ...Properties...
#region ... Methods ...
#endregion ...Methods...
#region ... Interfaces ...
#endregion ...Interfaces...
}
}
......@@ -147,7 +147,7 @@ namespace Cdy.Tag
private int mStartMergeCount = 0;
private Dictionary<long,Dictionary<DateTime, ManualHisDataMemoryBlock>> mManualHisDataCach = new Dictionary<long, Dictionary<DateTime, ManualHisDataMemoryBlock>>();
private Dictionary<long,SortedDictionary<DateTime, ManualHisDataMemoryBlock>> mManualHisDataCach = new Dictionary<long, SortedDictionary<DateTime, ManualHisDataMemoryBlock>>();
#endregion ...Variables...
......@@ -198,6 +198,29 @@ namespace Cdy.Tag
}
}
/// <summary>
/// 当前正在使用的内存
/// </summary>
public HisDataMemoryBlockCollection CurrentMergeMemory
{
get
{
return mCurrentMergeMemory;
}
}
/// <summary>
///
/// </summary>
public Cdy.Tag.HisDatabase HisTagManager
{
get
{
return mManager;
}
}
/// <summary>
///
/// </summary>
......@@ -853,6 +876,8 @@ namespace Cdy.Tag
CurrentMemory = mCachMemory1;
CurrentMemory.CurrentDatetime = mLastProcessTime;
HisDataMemoryQueryService.Service.RegistorMemory(CurrentMemory.CurrentDatetime, mLastProcessTime.AddSeconds(CachMemoryTime), CurrentMemory);
mCurrentMergeMemory = mMergeMemory1;
mCurrentMergeMemory.CurrentDatetime = CurrentMemory.CurrentDatetime;
......@@ -925,6 +950,9 @@ namespace Cdy.Tag
//mMergeMemory.Dump();
mCurrentMergeMemory.EndDateTime = mSnapAllTagTime;
HisDataMemoryQueryService.Service.RegistorMemory(mCurrentMergeMemory.CurrentDatetime, mCurrentMergeMemory.EndDateTime, mCurrentMergeMemory);
mCurrentMergeMemory.MakeMemoryBusy();
//提交到数据压缩流程
ServiceLocator.Locator.Resolve<IDataCompress2>().RequestToCompress(mCurrentMergeMemory);
......@@ -971,7 +999,6 @@ namespace Cdy.Tag
Stopwatch sw = new Stopwatch();
sw.Start();
//System.Threading.Tasks.Parallel.ForEach(mHisTags, (tag) => {
foreach (var tag in mHisTags)
{
var taddrs = mCurrentMergeMemory.TagAddress[tag.Value.Id];
......@@ -999,13 +1026,11 @@ namespace Cdy.Tag
vtimeaddr = taddrs.QualityAddress + dlen * count + 1;
saddrs.CopyTo(taddrs, saddrs.QualityAddress, vtimeaddr, dlen);
}
//});
//mCurrentMergeMemory.Dump();
//mcc.Dump();
mcc.MakeMemoryNoBusy();
//ClearMemoryHisData(mcc);
HisDataMemoryQueryService.Service.ClearMemoryTime(mcc.CurrentDatetime);
HisDataMemoryQueryService.Service.RegistorMemory(mCurrentMergeMemory.CurrentDatetime, mcc.EndDateTime, mCurrentMergeMemory);
mcc.MakeMemoryNoBusy();
sw.Stop();
LoggerService.Service.Info("Record", "合并完成 " + mcc.Name+" 次数:"+(count+1)+" 耗时:"+sw.ElapsedMilliseconds);
}
......@@ -1039,6 +1064,8 @@ namespace Cdy.Tag
CurrentMemory.CurrentDatetime = dateTime;
HisDataMemoryQueryService.Service.RegistorMemory(CurrentMemory.CurrentDatetime,dateTime.AddSeconds(CachMemoryTime), CurrentMemory);
if (mMergeCount==0)
{
mNeedSnapAllTag = true;
......@@ -1354,7 +1381,7 @@ namespace Cdy.Tag
DateTime mLastTime = DateTime.MinValue;
Dictionary<DateTime, ManualHisDataMemoryBlock> datacach;
SortedDictionary<DateTime, ManualHisDataMemoryBlock> datacach;
if (mHisTags.ContainsKey(id) && mHisTags[id].Type == RecordType.Manual)
{
......@@ -1364,7 +1391,7 @@ namespace Cdy.Tag
}
else
{
datacach = new Dictionary<DateTime, ManualHisDataMemoryBlock>();
datacach = new SortedDictionary<DateTime, ManualHisDataMemoryBlock>();
mManualHisDataCach.Add(id, datacach);
}
......@@ -1381,6 +1408,8 @@ namespace Cdy.Tag
}
else
{
if(hb!=null)
HisDataMemoryQueryService.Service.RegistorManual(id, hb.Time, hb.EndTime, hb);
var css = CalCachDatablockSize(tag.TagType, 0, MergeMemoryTime * 1000 / timeUnit, out valueOffset, out qulityOffset);
hb = ManualHisDataMemoryBlockPool.Pool.Get(css);
hb.Time = time;
......@@ -1391,8 +1420,9 @@ namespace Cdy.Tag
hb.ValueAddress = valueOffset;
hb.QualityAddress = qulityOffset;
hb.Id = (int)id;
HisDataMemoryQueryService.Service.RegistorManual(id, hb.Time, time, hb);
datacach.Add(time, hb);
}
mLastTime = time;
......@@ -1492,6 +1522,8 @@ namespace Cdy.Tag
hb.Relase();
}
}
if (hb != null)
HisDataMemoryQueryService.Service.RegistorManual(id, hb.Time, hb.EndTime, hb);
bool isNeedSubmite = false;
......@@ -1533,7 +1565,7 @@ namespace Cdy.Tag
DateTime mLastTime = DateTime.MinValue;
Dictionary<DateTime, ManualHisDataMemoryBlock> datacach;
SortedDictionary<DateTime, ManualHisDataMemoryBlock> datacach;
if (mHisTags.ContainsKey(id) && mHisTags[id].Type == RecordType.Manual)
{
......@@ -1543,7 +1575,7 @@ namespace Cdy.Tag
}
else
{
datacach = new Dictionary<DateTime, ManualHisDataMemoryBlock>();
datacach = new SortedDictionary<DateTime, ManualHisDataMemoryBlock>();
mManualHisDataCach.Add(id, datacach);
}
......@@ -1669,6 +1701,9 @@ namespace Cdy.Tag
hb.EndTime = value.Time;
hb.CurrentCount++;
hb.Relase();
HisDataMemoryQueryService.Service.RegistorManual(id, hb.Time, hb.EndTime, hb);
}
bool isNeedSubmite = false;
......
......@@ -616,7 +616,13 @@ namespace Cdy.Tag
return this;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override bool IsOpened()
{
return mStream != null;
}
}
}
......@@ -225,7 +225,7 @@ namespace Cdy.Tag
/// <param name="tags"></param>
private void ProcessTags(List<HisRunTag> tags)
{
int tim = (int)((mLastUpdateTime - HisRunTag.StartTime).TotalMilliseconds / HisEnginer.MemoryTimeTick);
int tim = (int)((mLastUpdateTime - HisRunTag.StartTime).TotalMilliseconds / HisEnginer2.MemoryTimeTick);
foreach (var vv in tags)
{
vv.UpdateValue2(tim);
......
......@@ -8,6 +8,7 @@
//==============================================================
using Cdy.Tag.Driver;
using DBRuntime;
using DBRuntime.His;
using System;
using System.Collections.Generic;
using System.Diagnostics;
......@@ -306,6 +307,11 @@ namespace Cdy.Tag
ServiceLocator.Locator.Registor<IHisEngine2>(hisEnginer);
ServiceLocator.Locator.Registor<ITagHisValueProduct>(hisEnginer);
//初始化从内存中查询数据的服务
HisDataMemoryQueryService.Service.HisEnginer = hisEnginer;
ServiceLocator.Locator.Registor<IHisQueryFromMemory>(HisDataMemoryQueryService.Service);
compressEnginer = new CompressEnginer2();
compressEnginer.TagCountOneFile = mHisDatabase.Setting.TagCountOneFile;
compressEnginer.Init();
......
......@@ -2,7 +2,7 @@
"profiles": {
"HisDataTools": {
"commandName": "Executable",
"executablePath": "C:\\Users\\cdy81\\source\\repos\\mars\\Output\\HisDataTools.exe"
"executablePath": "C:\\Users\\chongdaoyang\\source\\repos\\mars\\Output\\HisDataTools.exe"
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册