增加历史数据存储处理类

This commit is contained in:
大石头 2017-04-15 12:40:32 +08:00
parent 309597bc76
commit ef3bf65a5f
3 changed files with 224 additions and 2 deletions

View File

@ -9,8 +9,8 @@ typedef void(*Action2)(void*, void*);
typedef void(*Action3)(void*, void*, void*);
// 事件处理委托一般sender表示事件发出者param用作目标对象调用者用静态函数包装成员函数
typedef void (*EventHandler)(void* sender, void* param);
// 传入数据缓冲区地址和长度,如有反馈,仍使用该缓冲区,返回数据长度
typedef uint (*DataHandler)(void* sender, byte* buf, uint size, void* param);
// 数据处理
typedef uint (*DataHandler)(void* sender, Buffer& bs, void* param);
// 委托接口
class IDelegate

166
Message/HistoryStore.cpp Normal file
View File

@ -0,0 +1,166 @@
#include "Kernel\Sys.h"
#include "HistoryStore.h"
//#define DS_DEBUG DEBUG
#define DS_DEBUG 0
#if DS_DEBUG
#define ds_printf debug_printf
#else
#define ds_printf(format, ...)
#endif
// 初始化
HistoryStore::HistoryStore()
{
Opened = false;
RenderPeriod = 30;
ReportPeriod = 300;
FlashPeriod = 600;
MaxCache = 16 * 1024;
MaxReport = 1024;
OnReport = nullptr;
OnFlash = nullptr;
_task = 0;
}
HistoryStore::~HistoryStore()
{
Close();
}
void HistoryStore::Set(void* data, int size)
{
Data = data;
Size = size;
}
bool HistoryStore::Open()
{
if (Opened) return true;
_Report = 0;
_Flash = 0;
// 定时生成历史数据 30s
int p = RenderPeriod * 1000;
_task = Sys.AddTask(RenderTask, this, p, p, "历史数据");
return Opened = true;
}
void HistoryStore::Close()
{
Sys.RemoveTask(_task);
Opened = false;
}
// 写入一条历史数据
int HistoryStore::Write(const Buffer& bs)
{
int size = bs.Length();
if (size == 0) return 0;
auto& s = Cache;
auto p = s.Position();
// 历史数据格式4时间 + N数据
s.Write(Sys.Seconds());
s.Write(bs);
return s.Position() - p;
}
void HistoryStore::RenderTask(void* param)
{
auto hs = (HistoryStore*)param;
if (hs) hs->Reader();
}
void HistoryStore::Reader()
{
// 生成历史数据
Buffer bs(Data, Size);
Write(bs);
// 自动上传
if (_Report <= 0) _Report = ReportPeriod;
_Report -= RenderPeriod;
if (_Report <= 0) Report();
// 自动写入Flash
if (_Flash <= 0) _Flash = FlashPeriod;
_Flash -= RenderPeriod;
if (_Flash <= 0) Flash();
}
void HistoryStore::Report()
{
if (!OnReport) return;
auto& s = Cache;
// 没有数据
if (s.Position() == s.Length) return;
// 根据每次最大上报长度,计算可以上报多少条历史记录
int n = MaxReport / Size;
int len = n * Size;
ByteArray bs(len);
len = s.Read(bs);
bs.SetLength(len);
// 游标先移回去,成功以后再删除
s.Seek(-len);
if (len) {
int len2 = OnReport(this, bs, nullptr);
if (len2) {
s.Seek(len2);
// 如果缓存里面没有了数据,则从头开始使用
if (s.Position() == s.Length) {
s.SetPosition(0);
s.Length = 0;
}
}
}
}
void HistoryStore::Flash()
{
if (!OnFlash) return;
auto& s = Cache;
// 没有数据
if (s.Position() == s.Length) return;
// 根据每次最大上报长度,计算可以上报多少条历史记录
int n = MaxReport / Size;
int len = n * Size;
ByteArray bs(len);
len = s.Read(bs);
bs.SetLength(len);
// 游标先移回去,成功以后再删除
s.Seek(-len);
if (len) {
int len2 = OnFlash(this, bs, nullptr);
if (len2) {
s.Seek(len2);
// 如果缓存里面没有了数据,则从头开始使用
if (s.Position() == s.Length) {
s.SetPosition(0);
s.Length = 0;
}
}
}
}

56
Message/HistoryStore.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef __HistoryStore_H__
#define __HistoryStore_H__
#include "Core\\Delegate.h"
// 历史数据存储
class HistoryStore
{
public:
MemoryStream Cache; // 数据
short RenderPeriod; // 生成历史数据周期。默认30s
short ReportPeriod; // 上报数据周期。默认300s
short FlashPeriod; // 写入Flash周期。默认600s
short MaxCache; // 缓存最大长度。默认16 * 1024
short MaxReport; // 每次最大上报长度。默认1024
bool Opened;
// 数据上报句柄
DataHandler OnReport;
// 数据存储句柄
DataHandler OnFlash;
// 初始化
HistoryStore();
~HistoryStore();
void Set(void* data, int size);
bool Open();
void Close();
// 写入一条历史数据
int Write(const Buffer& bs);
private:
void* Data;
int Size;
short _Report;
short _Flash;
uint _task;
static void RenderTask(void* param);
void Reader();
void Report();
void Flash();
};
/*
4 + N数据
*/
#endif