fix error in recall when hours more than 300

This commit is contained in:
lnk
2025-08-01 16:31:57 +08:00
parent acbaf89459
commit 3b5b14f9ae
5 changed files with 200 additions and 19 deletions

View File

@@ -2183,11 +2183,76 @@ int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int
//WW2023-11-01 end
//补招部分////////////////////////////////////////////////////////////////////////////////
////////////////////////////20250801
/* 最小块,每次至少扩容这么多;也可以调大一点 */
#define RECALL_CHUNK 64
/* 初始化 */
void recall_xml_init(recall_xml_t *rx) // ★
{
rx->work_cnt = rx->work_cap = 0;
rx->new_cnt = rx->new_cap = 0;
rx->work_recalls = rx->new_recalls = nullptr;
}
/* 若需要,扩容 `*arr` 直到能放下 needed 条记录 */
static int ensure_cap(recall_t **arr, int *cap, int need)
{
if (need <= *cap) return 0;
int new_cap = (*cap) ? (*cap) : 16;
while (new_cap < need) new_cap <<= 1;
/* C++ 里要显式转换 */
void *mem = realloc(*arr, new_cap * sizeof(recall_t));
if (!mem) return -1;
*arr = static_cast<recall_t *>(mem); // ★ 显式 static_cast
*cap = new_cap;
return 0;
}
/* push 到 work / new 数组 */
static int push_work(recall_xml_t *rx, const recall_t *rec)
{
if (ensure_cap(&rx->work_recalls, &rx->work_cap, rx->work_cnt + 1))
return -1;
rx->work_recalls[rx->work_cnt++] = *rec;
return 0;
}
static int push_new(recall_xml_t *rx, const recall_t *rec)
{
if (ensure_cap(&rx->new_recalls, &rx->new_cap, rx->new_cnt + 1))
return -1;
rx->new_recalls[rx->new_cnt++] = *rec;
return 0;
}
/* 释放内存(栈退出前或不用时调用) */
void recall_xml_free(recall_xml_t *rx) // ★
{
for (int i = 0; i < rx->work_cnt; ++i)
free(rx->work_recalls[i].line_id);
for (int i = 0; i < rx->new_cnt; ++i)
free(rx->new_recalls[i].line_id);
free(rx->work_recalls);
free(rx->new_recalls);
recall_xml_init(rx); /* 复位为全 0防止悬挂指针 */
}
////////////////////////////20250801
void parse_recall(recall_xml_t* recall_xml, QString parentTag, QDomElement& recall_e, char* id)
{
recall_t recall;
//recall_t recall;//lnk20250801
recall.line_id = id;
//recall.line_id = id;
recall_t recall = {0};
recall.line_id = strdup(id); /* malloc 字符串 */
QDateTime start_dt = QDateTime::fromString(recall_e.attribute("StartTime"), "yyyy-MM-dd hh:mm:ss");
recall.start_time = start_dt.toMSecsSinceEpoch() / 1000;
@@ -2201,10 +2266,12 @@ void parse_recall(recall_xml_t* recall_xml, QString parentTag, QDomElement& reca
<< " " << recall.start_time << " " << recall.end_time;
if (parentTag == "Work") {
recall_xml->work_recalls[recall_xml->work_recall_num++] = recall;
//recall_xml->work_recalls[recall_xml->work_recall_num++] = recall;
push_work(recall_xml, &recall);
}
else if (parentTag == "New") {
recall_xml->new_recalls[recall_xml->new_recall_num++] = recall;
//recall_xml->new_recalls[recall_xml->new_recall_num++] = recall;
push_new(recall_xml, &recall);
}
}
@@ -2295,7 +2362,7 @@ int parse_recall_xml(recall_xml_t* recall_xml, char* id)
return APR_SUCCESS;
}
void process_recall_config(recall_xml_t* recall_xml)
/*void process_recall_config(recall_xml_t* recall_xml)
{
int i, j;
recall_t* recall;
@@ -2328,13 +2395,18 @@ void process_recall_config(recall_xml_t* recall_xml)
if (LD_info->autorecallflag != 0 || LD_info->autorecallcount == 0) { //
if (LD_info->autorecallcount != 0) {
for (int j = 0; j < LD_info->autorecallcount; j++) {
delete LD_info->autorecall[j];
delete[] LD_info->autorecall[j];//避免重复释放lnk20250801
}
delete LD_info->autorecall;
LD_info->autorecallcount = 0;
}
LD_info->autorecallcount = recall_num;
LD_info->autorecall = new autorecall_t * [recall_num];
for (int k = 0; k < recall_num; ++k) {
LD_info->autorecall[k] = nullptr; //避免野指针lnk20250801
}
for (int j = 0; j < recall_num; j++) {
printf("\n %d ===== %d\n", recall[j].start_time, recall[j].end_time);
LD_info->autorecall[j] = new autorecall_t[1];
@@ -2352,10 +2424,104 @@ void process_recall_config(recall_xml_t* recall_xml)
}
}
//调试
printf("== autorecall count = %d ==\n", LD_info->autorecallcount);
for (int j = 0; j < LD_info->autorecallcount; ++j) {
if (LD_info->autorecall[j] == nullptr) {
printf("autorecall[%d] = nullptr !!!\n", j);
} else {
printf("autorecall[%d] = %p | start = %d, end = %d\n",
j, LD_info->autorecall[j],
LD_info->autorecall[j]->start, LD_info->autorecall[j]->end);
}
}
}
}
}*/
void process_recall_config(recall_xml_t *rx)
{
if (rx->new_cnt) {
/* 预留空间 */
if (ensure_cap(&rx->work_recalls, &rx->work_cap,
rx->work_cnt + rx->new_cnt))
return; /* 内存不足,直接返回 */
memcpy(&rx->work_recalls[rx->work_cnt],
rx->new_recalls,
rx->new_cnt * sizeof(recall_t));
rx->work_cnt += rx->new_cnt;
rx->new_cnt = 0;
}
/* work 列表为空,直接结束 */
if (rx->work_cnt == 0)
return;
recall_t *recall = rx->work_recalls;
int recall_num = rx->work_cnt;
LD_info_t *LD_info = find_LD_info_only_from_mp_id(recall[0].line_id);
printf("\n recall[0].line_id == %s \n", recall[0].line_id);
printf("\n recall[0].start_time == %lld \n", recall[0].start_time);
if (!LD_info || LD_info->read_flag == 0) {
printf("\n Find LD_info == null \n");
return;
}
printf("\n Find LD_info != null \n");
/* 若正在补招中则跳过;否则装载新补招队列 */
if (LD_info->autorecallflag != 0 || LD_info->autorecallcount == 0) {
/* 先释放旧队列 */
if (LD_info->autorecallcount != 0) {
for (int j = 0; j < LD_info->autorecallcount; ++j)
delete[] LD_info->autorecall[j]; /* 原逻辑 */
delete LD_info->autorecall;
LD_info->autorecallcount = 0;
}
/* 重新分配新队列,大小 = recall_num */
LD_info->autorecallcount = recall_num;
LD_info->autorecall = new autorecall_t*[recall_num];
for (int k = 0; k < recall_num; ++k)
LD_info->autorecall[k] = nullptr;
for (int j = 0; j < recall_num; ++j) {
LD_info->autorecall[j] = new autorecall_t[1];
LD_info->autorecall[j]->start = recall[j].start_time;
LD_info->autorecall[j]->end = recall[j].end_time;
LD_info->autorecall[j]->need_steady = recall[j].need_steady;
LD_info->autorecall[j]->need_voltage = recall[j].need_voltage;
printf("\n %lld ===== %lld\n",
recall[j].start_time, recall[j].end_time);
}
LD_info->autorecallflag = 0; /* 重置“正在补招”标志 */
}
/* 调试输出 */
if(DEBUGOPEN){
printf("== autorecall count = %d ==\n", LD_info->autorecallcount);
for (int j = 0; j < LD_info->autorecallcount; ++j) {
if (!LD_info->autorecall[j])
printf("autorecall[%d] = nullptr !!!\n", j);
else
printf("autorecall[%d] = %p | start = %lld, end = %lld\n",
j, LD_info->autorecall[j],
LD_info->autorecall[j]->start,
LD_info->autorecall[j]->end);
}
}
}
//////////////////////////////////////////////////////////////////////////////////
void WebSocketThread::run()
@@ -5881,7 +6047,7 @@ void clearLDInfo(LD_info_t *ld_info) {
for (int i = 0; i < ld_info->autorecallcount; ++i) {
if (ld_info->autorecall[i] != nullptr) {
memset(ld_info->autorecall[i], 0, sizeof(autorecall_t));
delete ld_info->autorecall[i]; //删除数组元素空间,如果有正在补招的内容,则已经申请空间,需要释放
delete[] ld_info->autorecall[i]; //删除数组元素空间,如果有正在补招的内容,则已经申请空间,需要释放lnk20250801
}
}
delete ld_info->autorecall; //删除数组空间

View File

@@ -93,7 +93,6 @@ mqconsumerThread mqconsumerThrd;//mq消费者线程lnk20241213
OnTimerThread onTimerThrd;//定时线程
extern int g_iSqlListSize; //Sql执行语句链表允许最大元素个数 注Sql链表中元素超过此个数多出元素需移除
extern int FILE_FLAG;
extern int SEND_FLAG;
extern char* BROKER_LIST;

View File

@@ -696,7 +696,7 @@ void process_3s_config(trigger_3s_xml_t *trigger_3s_xml)
create_3s_xml(trigger_3s_xml); //写入文件的work块
}
void del_process_recall_config(recall_xml_t* recall_xml)
/*void del_process_recall_config(recall_xml_t* recall_xml)
{
int i,j;
recall_t *recall;
@@ -733,7 +733,7 @@ void del_process_recall_config(recall_xml_t* recall_xml)
}
}
}*/
void check_3s_config()
{
@@ -1402,9 +1402,14 @@ void Check_Recall_Config(char *id) //检查补招配置文件Recall.xml
if (g_node_id == HIS_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID || g_node_id == RECALL_HIS_DATA_BASE_NODE_ID || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID)) {
recall_xml_t recall_xml;
memset((char*)&recall_xml, 0, sizeof(recall_xml_t));
//memset((char*)&recall_xml, 0, sizeof(recall_xml_t));
recall_xml_init(&recall_xml);
parse_recall_xml(&recall_xml,id); //解析补招文件,目录下所有属于这个监测点的文件都读取
process_recall_config(&recall_xml); //解析的补招数据赋值到全局变量
recall_xml_free(&recall_xml);
}
}

View File

@@ -56,6 +56,8 @@ SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
extern pt61850app_t* g_pt61850app;
extern bool DEBUGOPEN;
/************************************************************************/
/* Static function prototypes. */
/************************************************************************/
@@ -126,7 +128,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
double start, end;
static double last_check_recall_config_time = 0.0;
printf("\nbrf for");
if(DEBUGOPEN)printf("\nbrf for");
for (j = 0; j < jou_entry->ef.data.num_of_var; j++) {
printf("\nfor %d", jou_entry->ef.data.num_of_var);
@@ -146,7 +148,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
do_name++;
}
printf("\nbrf if");
if(DEBUGOPEN)printf("\nbrf if");
if (sel_mvl_type_ctrl_flag(do_name) == -1)
{
var_type_id = mms_var_type_id_create(clientNetInfo, DOM_SPEC,
@@ -157,15 +159,15 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t,
add_mvl_type_ctrl(doname, var_type_id);
}
printf("\nbrf var_type_id");
if(DEBUGOPEN)printf("\nbrf var_type_id");
var_type_id = sel_mvl_type_ctrl_flag(do_name);
printf("\nafter var_type_id");
if(DEBUGOPEN)printf("\nafter var_type_id");
if (var_type_id < 0) {
continue;
}
log_var_jou_data(var_type_id,&(jou_entry->ef.data.list_of_var[j].value_spec),&mms_dec_data, do_name);
printf("\nafter log_var_jou_data");
if(DEBUGOPEN)printf("\nafter log_var_jou_data");
if (timeflag) {
int readtime = 0;
int readquailty = 0;

View File

@@ -144,13 +144,19 @@ struct recall_t{
int need_voltage;
};
typedef struct recall_xml_t recall_xml_t;
struct recall_xml_t{
/*struct recall_xml_t{
int work_recall_num;
int new_recall_num;
recall_t work_recalls[MAX_RECALL_NUM];
recall_t new_recalls[MAX_RECALL_NUM];
};*/
/* 动态数组 + 容量字段 lnk20250801*/
struct recall_xml_t{
int work_cnt, work_cap;
int new_cnt , new_cap;
recall_t *work_recalls;
recall_t *new_recalls;
};
/////////////////////////////////////////////////////////////
struct element_usr_t{
char* FCD_ref;
@@ -494,6 +500,9 @@ int delete_recall_xml(char* id);
int parse_recall_xml(recall_xml_t* recall_xml,char *id);
void process_recall_config(recall_xml_t* recall_xml);
void recall_xml_free(recall_xml_t *rx);//lnk20250801
void recall_xml_init(recall_xml_t *rx);
int init_rptctrl_by_count(LD_info_t* LD_info,int rptcount);
int fill_rptctrl_by_cfg(LD_info_t* LD_info,int rptno,char *buf);
int init_logctrl_by_count(LD_info_t* LD_info,int logcount);