SmartOS/Message/HistoryStore.cpp

201 lines
3.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Kernel\Sys.h"
#include "Device\Flash.h"
#include "Kernel\Task.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;
StorePeriod = 600;
MaxCache = 16 * 1024;
MaxReport = 1024;
OnWrite = nullptr;
OnReport = nullptr;
OnStore = nullptr;
_task = 0;
}
HistoryStore::~HistoryStore()
{
Close();
}
void HistoryStore::Set(void* data, int size)
{
Data = data;
Size = size;
}
bool HistoryStore::Open(bool UseThousand)
{
if (Opened) return true;
ds_printf("HistoryStore::Open Render=%ds Report=%ds Store=%ds \r\n", RenderPeriod, ReportPeriod, StorePeriod);
_Report = 0;
_Store = 0;
int p;
if(UseThousand)
{
// 定时生成历史数据 30s
p = RenderPeriod * 1000;
}
else
{
p = RenderPeriod;
}
_task = Sys.AddTask(RenderTask, this, p, p, "历史数据");
auto task = Task::Get(_task);
task->MaxDeepth = 4;
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();
// 移到最后
s.SetPosition(s.Length);
// 历史数据格式4时间 + N数据
s.Write(Sys.Seconds());
s.Write(bs);
// 回到原来位置
s.SetPosition(p);
return 4 + bs.Length();
}
void HistoryStore::RenderTask(void* param)
{
auto hs = (HistoryStore*)param;
if (hs) hs->Reader();
}
void HistoryStore::Reader()
{
//ds_printf("HistoryStore::Reader %d/%d/%d \r\n", Size, Cache.Position(), Cache.Length);
Process(OnWrite);
// 生成历史数据
Buffer bs(Data, Size);
Write(bs);
// 自动上传
if (_Report <= 0) _Report = ReportPeriod;
_Report -= RenderPeriod;
if (_Report <= 0) Report();
// 自动写入Store
if (_Store <= 0) _Store = StorePeriod;
_Store -= RenderPeriod;
if (_Store <= 0) Store();
//ds_printf("_Report=%d _Store=%d \r\n", _Report, _Store);
}
void HistoryStore::Report()
{
if (!OnReport) return;
auto& s = Cache;
int len = s.Length - s.Position();
// 没有数据
if (!len) return;
// 根据每次最大上报长度,计算可以上报多少条历史记录
int n = MaxReport / (4 + Size);
int len2 = n * (4 + Size);
if (len2 > len) len2 = len;
//ds_printf("HistoryStore::Report %d/%d \r\n", len2, len);
Process(len2, OnReport);
}
void HistoryStore::Store()
{
if (!OnStore) return;
auto& s = Cache;
int len = s.Length - s.Position();
// 没有数据
if (!len) return;
ds_printf("HistoryStore::Store %d \r\n", len);
Process(len, OnStore);
}
void HistoryStore::Process(EventHandler handler)
{
if (!handler) return;
handler(this, nullptr);
}
void HistoryStore::Process(int len, DataHandler handler)
{
if (!len || !handler) return;
auto& s = Cache;
Buffer bs(s.GetBuffer() + s.Position(), len);
int rs = handler(this, bs, nullptr);
if (rs) {
s.Seek(rs);
// 如果缓存里面没有了数据,则从头开始使用
if (s.Position() == s.Length) {
s.SetPosition(0);
s.Length = 0;
}
}
}
// 存储数据到Flash上指定地址
uint HistoryStore::ReadFlash(uint address, Buffer& bs)
{
Flash flash;
return bs.Length();
}
uint HistoryStore::WriteFlash(uint address, const Buffer& bs)
{
Flash flash;
return bs.Length();
}