Heart 1.3.848.aa44c26
Heart is base back end library for your c++ Qt projects.
bigdataparser.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022-2025 QuasarApp.
3 * Distributed under the lgplv3 software license, see the accompanying
4 * Everyone is permitted to copy and distribute verbatim copies
5 * of this license document, but changing it is not allowed.
6*/
7
8#include "bigdataparser.h"
9#include "bigdataheader.h"
10#include "bigdatapart.h"
11
12#include <bigdatarequest.h>
13#include <abstractnode.h>
14#include <cmath>
15#include <params.h>
16#include <bigdatawraper.h>
17
18#define TIMEOUT_INTERVAL 30000
19
20namespace QH {
21
30
66
68 return 1;
69}
70
71QString BigDataParser::parserId() const {
72 return "HeartBigDataAPI";
73}
74
75void QH::BigDataParser::insertNewBigData(const QSharedPointer<PKG::BigDataHeader> &header) {
76 if (!_pool.contains(header->packageId())) {
77 QVector<QSharedPointer<PKG::BigDataPart>> _array;
78 _array.resize(header->getPackagesCount());
79 _pool[header->packageId()] = {header, _array, static_cast<int>(time(0))};
80 }
81
82 checkOutDatedPacakges(header->packageId());
83}
84
85bool BigDataParser::newPackage(const QSharedPointer<PKG::BigDataHeader> &header,
86 AbstractNodeInfo *sender,
87 const Header & hdr) {
88
89 if (!header->isValid())
90 return false;
91
92 insertNewBigData(header);
93
96 request.setPackageId(header->packageId());
97
98 qDebug() << "Receive BigData Header:" << header->toString();
99
100 return node()->sendData(&request, sender, &hdr);
101}
102
103bool BigDataParser::processPart(const QSharedPointer<PKG::BigDataPart> &part,
104 AbstractNodeInfo *sender,
105 const Header & hdr) {
106
107 if (!_pool.contains(part->packageId())) {
108 return false;
109 }
110
111 checkOutDatedPacakges(part->packageId());
112
113 auto& localPool = _pool[part->packageId()];
114
115 qDebug () << "Process Part of" << part->packageId() << ": part" << part->getPakckageNumber() << "/" << localPool.chaindata.size() - 1;
116
117 localPool.chaindata[part->getPakckageNumber()] = part;
118
119 auto sendRequest = [sender, &hdr, this](int part, unsigned int id){
120
123 request.setPackageId(id);
124
125 return node()->sendData(&request, sender, &hdr);
126 };
127
128 if (part->getPakckageNumber() + 1 < localPool.chaindata.size()) {
129 return sendRequest(part->getPakckageNumber() + 1,
130 part->packageId());
131
132 }
133
134 auto package = node()->genPackage(localPool.header->getCommand(),
135 sender);
136 if (!package)
137 return false;
138
140 for (int idx = 0; idx < localPool.chaindata.size(); ++idx) {
141 if (localPool.chaindata[idx]) {
142 packageRawData += localPool.chaindata[idx]->data();
143 } else {
144 return sendRequest(idx, part->packageId());
145 }
146 }
147
148 package->fromBytes(packageRawData);
149
151 return false;
152 }
153
154 _pool.remove(part->packageId());
155
156 return true;
157}
158
161 const Header &pkgHeader) {
162
163
164 unsigned int id = request->packageId();
165
166 if (!_pool.contains(id)) {
167 qDebug() << "requested data is missing!";
168 return false;
169 }
170
171 checkOutDatedPacakges(id);
172
173 const auto &localPool = _pool[id];
174 if (request->currentPart() >= localPool.chaindata.size()) {
175 return false;
176 }
177
178 bool fLast = localPool.chaindata.size() - 1 == request->currentPart();
179
180 const auto &data = localPool.chaindata[request->currentPart()];
181 if (!node()->sendData(data.data(), sender, &pkgHeader)) {
182 return false;
183 }
184
185 if (fLast) {
186 _pool.remove(id);
187 }
188
189 return true;
190}
191
197
198bool BigDataParser::sendBigDataPackage(const PKG::AbstractData *data,
200 const QH::Header *pkgHeader) {
201
202 unsigned int sizeLimit = Package::maximumSize() - sizeof (PKG::BigDataPart);
203 auto rawData = data->toBytes();
204
205 auto hdr = QSharedPointer<PKG::BigDataHeader>::create();
206 hdr->setPackagesCount(std::ceil(rawData.size() / static_cast<double>(sizeLimit)));
207 hdr->setPackageId(rand());
208 hdr->setCommand(data->cmd());
209
210 insertNewBigData(hdr);
211
212 for (int i = 0; i < hdr->getPackagesCount(); ++i) {
213 auto part = QSharedPointer<PKG::BigDataPart>::create();
214 part->setPackageId(hdr->packageId());
215 part->setPakckageNumber(i);
216 part->setData(rawData.mid(i * sizeLimit, sizeLimit));
217
218 _pool[hdr->packageId()].chaindata[i] = part;
219 }
220
221
222 if (!node()->sendData(hdr.data(), sender, pkgHeader)) {
223 return false;
224 }
225
226 return true;
227}
228
229void BigDataParser::checkOutDatedPacakges(unsigned int currentProcessedId) {
230 int utx = time(0);
231
232 if (_pool.contains(currentProcessedId)) {
233 _pool[currentProcessedId].lastUpdate = utx;
234 }
235
236 for (auto key = _pool.keyBegin(); key != _pool.keyEnd(); ++key) {
237 if (utx - _pool[*key].lastUpdate > TIMEOUT_INTERVAL) {
238 _pool.remove(*key);
239 }
240 }
241}
242
243}
#define TIMEOUT_INTERVAL
The AbstractNodeInfo class contains information about client or server connection and tcp socket of n...
The AbstractNode class - Abstract implementation of node. this implementation have a methods for send...
virtual unsigned int sendData(const PKG::AbstractData *resp, const HostAddress &address, const Header *req=nullptr)
sendData This method send data object another to node
QString parserId() const override
parserId This is id of the parsers. All parser will be synced betwin nodes by ids.
ParserResult parsePackage(const QSharedPointer< PKG::AbstractData > &pkg, const Header &pkgHeader, AbstractNodeInfo *sender) override
parsePackage This is main method of all childs classes of an AbstractNode class. This method work on ...
bool processBigDataWraper(const QSharedPointer< PKG::BigDataWraper > &request, AbstractNodeInfo *sender, const Header &pkgHeader)
sendBigDataPackage This method separate big pacakge and sent only heder ot serve.
bool processPart(const QSharedPointer< PKG::BigDataPart > &part, AbstractNodeInfo *sender, const QH::Header &pkgHeader)
processPart This method process part of package
bool processRequest(const QSharedPointer< PKG::BigDataRequest > &request, QH::AbstractNodeInfo *sender, const QH::Header &pkgHeader)
finishPart This metho process last package of big data transaction.
BigDataParser(AbstractNode *parentNode)
int version() const override
version This method return version of parser object
bool newPackage(const QSharedPointer< PKG::BigDataHeader > &header, AbstractNodeInfo *sender, const Header &pkgHeader)
newPackage This method process first header packge of the big data.
The AbstractData class is provide base functions for transport data by network For create you own pac...
virtual unsigned short cmd() const =0
cmd - This is command of this object, (for generate cmd use macross QH_PACKAGE)
The BigDataPart class This data class used for transporting big data files greater than 64kb.
Definition bigdatapart.h:22
The BigDataRequest class contains missing package parts for redownload. If missing parts count is 0 t...
void setCurrentPart(int newCurrentPart)
setCurrentPart This method sets current new value of current page
static unsigned int maximumSize()
maximumSize This method return maximu size of pacakge. If pacakge large the maximum size then package...
Definition package.cpp:49
QByteArray toBytes() const
toBytes This method convert a current object to bytes array.
The iParser class This class provide functions for parsing income packages. For yousing just override...
Definition iparser.h:51
virtual unsigned int sendData(const PKG::AbstractData *resp, const HostAddress &address, const Header *req=nullptr) const
sendData This method send data object another to node
Definition iparser.cpp:50
void registerPackageType()
registerPackageType This method register package type T. This is need to prepare pacakge for parsing ...
Definition iparser.h:62
virtual ParserResult parsePackage(const QSharedPointer< PKG::AbstractData > &pkg, const Header &pkgHeader, AbstractNodeInfo *sender)=0
parsePackage This is main method of all childs classes of an AbstractNode class. This method work on ...
AbstractNode * node() const
Definition iparser.cpp:46
The QH namespace - QuasarApp Heart namespace. This namespace contains all classes of the Heart librar...
Definition heart.cpp:13
ParserResult
The ParserResult enum. Error - parser detect a errorob package. NotProcessed - the parser does not kn...
Definition iparser.h:35
@ NotProcessed
the parser does not know what to do with the package or has not finished processing it.
@ Error
parser detect a errorob package.
The Header struct 32 bytes.
Definition header.h:19