Heart 1.3.842.34c2ab5
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-2024 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 QuasarAppUtils::Params::log("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 QuasarAppUtils::Params::log(QString("Process Part of %0: part %1/%2").
116 arg(part->packageId()).
117 arg(part->getPakckageNumber()).
118 arg(localPool.chaindata.size() - 1));
119
120 localPool.chaindata[part->getPakckageNumber()] = part;
121
122 auto sendRequest = [sender, &hdr, this](int part, unsigned int id){
123
126 request.setPackageId(id);
127
128 return node()->sendData(&request, sender, &hdr);
129 };
130
131 if (part->getPakckageNumber() + 1 < localPool.chaindata.size()) {
132 return sendRequest(part->getPakckageNumber() + 1,
133 part->packageId());
134
135 }
136
137 auto package = node()->genPackage(localPool.header->getCommand(),
138 sender);
139 if (!package)
140 return false;
141
143 for (int idx = 0; idx < localPool.chaindata.size(); ++idx) {
144 if (localPool.chaindata[idx]) {
145 packageRawData += localPool.chaindata[idx]->data();
146 } else {
147 return sendRequest(idx, part->packageId());
148 }
149 }
150
151 package->fromBytes(packageRawData);
152
154 return false;
155 }
156
157 _pool.remove(part->packageId());
158
159 return true;
160}
161
164 const Header &pkgHeader) {
165
166
167 unsigned int id = request->packageId();
168
169 if (!_pool.contains(id)) {
170 QuasarAppUtils::Params::log("requested data is missing!");
171 return false;
172 }
173
174 checkOutDatedPacakges(id);
175
176 const auto &localPool = _pool[id];
177 if (request->currentPart() >= localPool.chaindata.size()) {
178 return false;
179 }
180
181 bool fLast = localPool.chaindata.size() - 1 == request->currentPart();
182
183 const auto &data = localPool.chaindata[request->currentPart()];
184 if (!node()->sendData(data.data(), sender, &pkgHeader)) {
185 return false;
186 }
187
188 if (fLast) {
189 _pool.remove(id);
190 }
191
192 return true;
193}
194
200
201bool BigDataParser::sendBigDataPackage(const PKG::AbstractData *data,
203 const QH::Header *pkgHeader) {
204
205 unsigned int sizeLimit = Package::maximumSize() - sizeof (PKG::BigDataPart);
206 auto rawData = data->toBytes();
207
208 auto hdr = QSharedPointer<PKG::BigDataHeader>::create();
209 hdr->setPackagesCount(std::ceil(rawData.size() / static_cast<double>(sizeLimit)));
210 hdr->setPackageId(rand());
211 hdr->setCommand(data->cmd());
212
213 insertNewBigData(hdr);
214
215 for (int i = 0; i < hdr->getPackagesCount(); ++i) {
216 auto part = QSharedPointer<PKG::BigDataPart>::create();
217 part->setPackageId(hdr->packageId());
218 part->setPakckageNumber(i);
219 part->setData(rawData.mid(i * sizeLimit, sizeLimit));
220
221 _pool[hdr->packageId()].chaindata[i] = part;
222 }
223
224
225 if (!node()->sendData(hdr.data(), sender, pkgHeader)) {
226 return false;
227 }
228
229 return true;
230}
231
232void BigDataParser::checkOutDatedPacakges(unsigned int currentProcessedId) {
233 int utx = time(0);
234
235 if (_pool.contains(currentProcessedId)) {
236 _pool[currentProcessedId].lastUpdate = utx;
237 }
238
239 for (auto key = _pool.keyBegin(); key != _pool.keyEnd(); ++key) {
240 if (utx - _pool[*key].lastUpdate > TIMEOUT_INTERVAL) {
241 _pool.remove(*key);
242 }
243 }
244}
245
246}
#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