1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "generic_single_ver_kv_entry.h"
17
18 #include <algorithm>
19 #include "data_compression.h"
20 #include "db_errno.h"
21 #include "parcel.h"
22 #include "version.h"
23
24 namespace DistributedDB {
GenericSingleVerKvEntry()25 GenericSingleVerKvEntry::GenericSingleVerKvEntry()
26 {
27 }
28
~GenericSingleVerKvEntry()29 GenericSingleVerKvEntry::~GenericSingleVerKvEntry()
30 {
31 }
32
GetOrigDevice() const33 std::string GenericSingleVerKvEntry::GetOrigDevice() const
34 {
35 return dataItem_.origDev;
36 }
37
SetOrigDevice(const std::string & dev)38 void GenericSingleVerKvEntry::SetOrigDevice(const std::string &dev)
39 {
40 dataItem_.origDev = dev;
41 }
42
GetTimestamp() const43 TimeStamp GenericSingleVerKvEntry::GetTimestamp() const
44 {
45 return dataItem_.timeStamp;
46 }
47
SetTimestamp(TimeStamp time)48 void GenericSingleVerKvEntry::SetTimestamp(TimeStamp time)
49 {
50 dataItem_.timeStamp = time;
51 }
52
GetWriteTimestamp() const53 TimeStamp GenericSingleVerKvEntry::GetWriteTimestamp() const
54 {
55 return dataItem_.writeTimeStamp;
56 }
57
SetWriteTimestamp(TimeStamp time)58 void GenericSingleVerKvEntry::SetWriteTimestamp(TimeStamp time)
59 {
60 dataItem_.writeTimeStamp = time;
61 }
62
SetEntryData(DataItem && dataItem)63 void GenericSingleVerKvEntry::SetEntryData(DataItem &&dataItem)
64 {
65 dataItem_ = dataItem;
66 }
67
GetKey(Key & key) const68 void GenericSingleVerKvEntry::GetKey(Key &key) const
69 {
70 key = dataItem_.key;
71 }
72
GetHashKey(Key & key) const73 void GenericSingleVerKvEntry::GetHashKey(Key &key) const
74 {
75 key = dataItem_.hashKey;
76 }
77
GetKey() const78 const Key &GenericSingleVerKvEntry::GetKey() const
79 {
80 return dataItem_.key;
81 }
82
GetValue(Value & value) const83 void GenericSingleVerKvEntry::GetValue(Value &value) const
84 {
85 value = dataItem_.value;
86 }
87
GetValue() const88 const Value &GenericSingleVerKvEntry::GetValue() const
89 {
90 return dataItem_.value;
91 }
92
GetFlag() const93 uint64_t GenericSingleVerKvEntry::GetFlag() const
94 {
95 return dataItem_.flag;
96 }
97
SetKey(const Key & key)98 void GenericSingleVerKvEntry::SetKey(const Key &key)
99 {
100 dataItem_.key = key;
101 }
102
SetValue(const Value & value)103 void GenericSingleVerKvEntry::SetValue(const Value &value)
104 {
105 dataItem_.value = value;
106 }
107
SetHashKey(const Key & hashKey)108 void GenericSingleVerKvEntry::SetHashKey(const Key &hashKey)
109 {
110 dataItem_.hashKey = hashKey;
111 }
112
113 // this func should do compatible
SerializeData(Parcel & parcel,uint32_t targetVersion)114 int GenericSingleVerKvEntry::SerializeData(Parcel &parcel, uint32_t targetVersion)
115 {
116 uint64_t len = 0;
117 int errCode = parcel.WriteUInt32(targetVersion);
118 if (errCode != E_OK) {
119 return errCode;
120 }
121 errCode = AdaptToVersion(OperType::SERIALIZE, targetVersion, parcel, len);
122 if (errCode != E_OK) {
123 return errCode;
124 }
125 return errCode;
126 }
127
SerializeDatas(const std::vector<SingleVerKvEntry * > & kvEntries,Parcel & parcel,uint32_t targetVersion)128 int GenericSingleVerKvEntry::SerializeDatas(const std::vector<SingleVerKvEntry *> &kvEntries, Parcel &parcel,
129 uint32_t targetVersion)
130 {
131 uint32_t size = kvEntries.size();
132 int errCode = parcel.WriteUInt32(size);
133 if (errCode != E_OK) {
134 LOGE("[SerializeDatas] write entries size failed, errCode=%d.", errCode);
135 return errCode;
136 }
137 parcel.EightByteAlign();
138 for (const auto &kvEntry : kvEntries) {
139 if (kvEntry == nullptr) {
140 continue;
141 }
142 errCode = kvEntry->SerializeData(parcel, targetVersion);
143 if (errCode != E_OK) {
144 LOGE("[SerializeDatas] write kvEntry failed, errCode=%d.", errCode);
145 return errCode;
146 }
147 }
148 return errCode;
149 }
150
151 // this func should do compatible
CalculateLen(uint32_t targetVersion)152 uint32_t GenericSingleVerKvEntry::CalculateLen(uint32_t targetVersion)
153 {
154 uint64_t len = 0;
155 int errCode = AdaptToVersion(OperType::CAL_LEN, targetVersion, len);
156 if ((len > INT32_MAX) || (errCode != E_OK)) {
157 return 0;
158 }
159 return len;
160 }
161
CalculateLens(const std::vector<SingleVerKvEntry * > & kvEntries,uint32_t targetVersion)162 uint32_t GenericSingleVerKvEntry::CalculateLens(const std::vector<SingleVerKvEntry *> &kvEntries,
163 uint32_t targetVersion)
164 {
165 uint64_t len = 0;
166 len += Parcel::GetUInt32Len();
167 len = BYTE_8_ALIGN(len);
168 for (const auto &kvEntry : kvEntries) {
169 if (kvEntry == nullptr) {
170 continue;
171 }
172 len += kvEntry->CalculateLen(targetVersion);
173 if (len > INT32_MAX) {
174 return 0;
175 }
176 }
177 return len;
178 }
179
180 // this func should do compatible
DeSerializeData(Parcel & parcel)181 int GenericSingleVerKvEntry::DeSerializeData(Parcel &parcel)
182 {
183 uint32_t version = VERSION_INVALID;
184 uint64_t len = parcel.ReadUInt32(version);
185 if (parcel.IsError()) {
186 return 0;
187 }
188 int errCode = AdaptToVersion(OperType::DESERIALIZE, version, parcel, len);
189 if (errCode != E_OK) {
190 len = 0;
191 }
192 return len;
193 }
194
DeSerializeDatas(std::vector<SingleVerKvEntry * > & kvEntries,Parcel & parcel)195 int GenericSingleVerKvEntry::DeSerializeDatas(std::vector<SingleVerKvEntry *> &kvEntries, Parcel &parcel)
196 {
197 uint64_t len = 0;
198 uint32_t size = 0;
199 len += parcel.ReadUInt32(size);
200 parcel.EightByteAlign();
201 len = BYTE_8_ALIGN(len);
202 for (uint32_t i = 0; i < size; i++) {
203 auto kvEntry = new (std::nothrow) GenericSingleVerKvEntry();
204 if (kvEntry == nullptr) {
205 LOGE("Create kvEntry failed.");
206 len = 0;
207 goto END;
208 }
209 len += kvEntry->DeSerializeData(parcel);
210 kvEntries.push_back(kvEntry);
211 if (len > INT32_MAX) {
212 len = 0;
213 goto END;
214 }
215 }
216 END:
217 if (len == 0) {
218 for (auto &kvEntry : kvEntries) {
219 delete kvEntry;
220 kvEntry = nullptr;
221 }
222 }
223 return len;
224 }
225
AdaptToVersion(OperType operType,uint32_t targetVersion,Parcel & parcel,uint64_t & datalen)226 int GenericSingleVerKvEntry::AdaptToVersion(OperType operType, uint32_t targetVersion, Parcel &parcel,
227 uint64_t &datalen)
228 {
229 if (targetVersion < SOFTWARE_VERSION_EARLIEST || targetVersion > SOFTWARE_VERSION_CURRENT) {
230 return -E_VERSION_NOT_SUPPORT;
231 }
232 int errCode = E_OK;
233 switch (operType) {
234 case OperType::SERIALIZE:
235 errCode = SerializeDataByVersion(targetVersion, parcel);
236 break;
237 case OperType::DESERIALIZE:
238 errCode = DeSerializeByVersion(targetVersion, parcel, datalen);
239 break;
240 default:
241 LOGE("Unknown upgrade serialize oper!");
242 return -E_UPGRADE_FAILED;
243 }
244 return errCode;
245 }
246
AdaptToVersion(OperType operType,uint32_t targetVersion,uint64_t & datalen)247 int GenericSingleVerKvEntry::AdaptToVersion(OperType operType, uint32_t targetVersion, uint64_t &datalen)
248 {
249 if (targetVersion < SOFTWARE_VERSION_EARLIEST || targetVersion > SOFTWARE_VERSION_CURRENT) {
250 return -E_VERSION_NOT_SUPPORT;
251 }
252
253 if (operType == OperType::CAL_LEN) {
254 return CalLenByVersion(targetVersion, datalen);
255 } else {
256 LOGE("Unknown upgrade serialize oper!");
257 return -E_UPGRADE_FAILED;
258 }
259 }
260
SerializeDataByFirstVersion(Parcel & parcel) const261 int GenericSingleVerKvEntry::SerializeDataByFirstVersion(Parcel &parcel) const
262 {
263 int errCode = parcel.WriteVectorChar(dataItem_.key);
264 if (errCode != E_OK) {
265 return errCode;
266 }
267 errCode = parcel.WriteVectorChar(dataItem_.value);
268 if (errCode != E_OK) {
269 return errCode;
270 }
271 errCode = parcel.WriteUInt64(dataItem_.timeStamp);
272 if (errCode != E_OK) {
273 return errCode;
274 }
275 errCode = parcel.WriteUInt64(dataItem_.flag);
276 if (errCode != E_OK) {
277 return errCode;
278 }
279
280 return parcel.WriteString(dataItem_.origDev);
281 }
282
SerializeDataByLaterVersion(Parcel & parcel,uint32_t targetVersion) const283 int GenericSingleVerKvEntry::SerializeDataByLaterVersion(Parcel &parcel, uint32_t targetVersion) const
284 {
285 TimeStamp writeTimeStamp = dataItem_.writeTimeStamp;
286 if (writeTimeStamp == 0) {
287 writeTimeStamp = dataItem_.timeStamp;
288 }
289 int errCode = parcel.WriteUInt64(writeTimeStamp);
290 if (errCode != E_OK) {
291 return errCode;
292 }
293 if (targetVersion >= SOFTWARE_VERSION_RELEASE_6_0) {
294 errCode = parcel.WriteVector(dataItem_.hashKey);
295 }
296 return errCode;
297 }
298
SerializeDataByVersion(uint32_t targetVersion,Parcel & parcel) const299 int GenericSingleVerKvEntry::SerializeDataByVersion(uint32_t targetVersion, Parcel &parcel) const
300 {
301 int errCode = SerializeDataByFirstVersion(parcel);
302 if (targetVersion == SOFTWARE_VERSION_EARLIEST || errCode != E_OK) {
303 return errCode;
304 }
305 return SerializeDataByLaterVersion(parcel, targetVersion);
306 }
307
CalLenByFirstVersion(uint64_t & len) const308 void GenericSingleVerKvEntry::CalLenByFirstVersion(uint64_t &len) const
309 {
310 len += Parcel::GetUInt32Len();
311 len += Parcel::GetVectorCharLen(dataItem_.key);
312 len += Parcel::GetVectorCharLen(dataItem_.value);
313 len += Parcel::GetUInt64Len();
314 len += Parcel::GetUInt64Len();
315 len += Parcel::GetStringLen(dataItem_.origDev);
316 }
317
CalLenByLaterVersion(uint64_t & len,uint32_t targetVersion) const318 void GenericSingleVerKvEntry::CalLenByLaterVersion(uint64_t &len, uint32_t targetVersion) const
319 {
320 len += Parcel::GetUInt64Len();
321 if (targetVersion >= SOFTWARE_VERSION_RELEASE_6_0) {
322 len += Parcel::GetVectorLen(dataItem_.hashKey);
323 }
324 }
325
CalLenByVersion(uint32_t targetVersion,uint64_t & len) const326 int GenericSingleVerKvEntry::CalLenByVersion(uint32_t targetVersion, uint64_t &len) const
327 {
328 CalLenByFirstVersion(len);
329 if (targetVersion == SOFTWARE_VERSION_EARLIEST) {
330 return E_OK;
331 }
332 CalLenByLaterVersion(len, targetVersion);
333 return E_OK;
334 }
335
DeSerializeByFirstVersion(uint64_t & len,Parcel & parcel)336 void GenericSingleVerKvEntry::DeSerializeByFirstVersion(uint64_t &len, Parcel &parcel)
337 {
338 len += parcel.ReadVectorChar(dataItem_.key);
339 len += parcel.ReadVectorChar(dataItem_.value);
340 len += parcel.ReadUInt64(dataItem_.timeStamp);
341 len += parcel.ReadUInt64(dataItem_.flag);
342 len += parcel.ReadString(dataItem_.origDev);
343 dataItem_.writeTimeStamp = dataItem_.timeStamp;
344 }
345
DeSerializeByLaterVersion(uint64_t & len,Parcel & parcel,uint32_t targetVersion)346 void GenericSingleVerKvEntry::DeSerializeByLaterVersion(uint64_t &len, Parcel &parcel, uint32_t targetVersion)
347 {
348 len += parcel.ReadUInt64(dataItem_.writeTimeStamp);
349 if (targetVersion >= SOFTWARE_VERSION_RELEASE_6_0) {
350 len += parcel.ReadVector(dataItem_.hashKey);
351 }
352 }
353
DeSerializeByVersion(uint32_t targetVersion,Parcel & parcel,uint64_t & len)354 int GenericSingleVerKvEntry::DeSerializeByVersion(uint32_t targetVersion, Parcel &parcel, uint64_t &len)
355 {
356 DeSerializeByFirstVersion(len, parcel);
357 if (targetVersion == SOFTWARE_VERSION_EARLIEST) {
358 return E_OK;
359 }
360 DeSerializeByLaterVersion(len, parcel, targetVersion);
361 return E_OK;
362 }
363
CalculateCompressedLens(const std::vector<uint8_t> & compressedData)364 uint32_t GenericSingleVerKvEntry::CalculateCompressedLens(const std::vector<uint8_t> &compressedData)
365 {
366 // No compressed data in sync.
367 if (compressedData.empty()) {
368 return 0;
369 }
370
371 // Calculate compressed data length.
372 uint64_t len = 0;
373 len += Parcel::GetUInt32Len(); // srcLen.
374 len += Parcel::GetUInt32Len(); // compression algorithm type.
375 len += Parcel::GetVectorLen(compressedData); // compressed data.
376 return (len > INT32_MAX) ? 0 : len;
377 }
378
Compress(const std::vector<SingleVerKvEntry * > & kvEntries,std::vector<uint8_t> & destData,const CompressInfo & compressInfo)379 int GenericSingleVerKvEntry::Compress(const std::vector<SingleVerKvEntry *> &kvEntries, std::vector<uint8_t> &destData,
380 const CompressInfo &compressInfo)
381 {
382 // Calculate length.
383 auto srcLen = CalculateLens(kvEntries, compressInfo.targetVersion);
384 if (srcLen == 0) {
385 LOGE("Over limit size, cannot compress.");
386 return -E_INVALID_ARGS;
387 }
388
389 // Serialize data.
390 std::vector<uint8_t> srcData(srcLen, 0);
391 Parcel parcel(srcData.data(), srcData.size());
392 int errCode = SerializeDatas(kvEntries, parcel, compressInfo.targetVersion);
393 if (errCode != E_OK) {
394 return errCode;
395 }
396
397 // Compress data.
398 auto inst = DataCompression::GetInstance(compressInfo.compressAlgo);
399 if (inst == nullptr) {
400 return -E_INVALID_COMPRESS_ALGO;
401 }
402 return inst->Compress(srcData, destData);
403 }
404
Uncompress(const std::vector<uint8_t> & srcData,std::vector<SingleVerKvEntry * > & kvEntries,unsigned long destLen,CompressAlgorithm algo)405 int GenericSingleVerKvEntry::Uncompress(const std::vector<uint8_t> &srcData, std::vector<SingleVerKvEntry *> &kvEntries,
406 unsigned long destLen, CompressAlgorithm algo)
407 {
408 // Uncompress data.
409 std::vector<uint8_t> destData(destLen, 0);
410 auto inst = DataCompression::GetInstance(algo);
411 if (inst == nullptr) {
412 return -E_INVALID_COMPRESS_ALGO;
413 }
414 int errCode = inst->Uncompress(srcData, destData, destLen);
415 if (errCode != E_OK) {
416 return errCode;
417 }
418
419 // Deserialize data.
420 Parcel parcel(destData.data(), destData.size());
421 if (DeSerializeDatas(kvEntries, parcel) == 0) {
422 return -E_PARSE_FAIL;
423 }
424 return E_OK;
425 }
426
SerializeCompressedDatas(const std::vector<SingleVerKvEntry * > & kvEntries,const std::vector<uint8_t> & compressedEntries,Parcel & parcel,uint32_t targetVersion,CompressAlgorithm algo)427 int GenericSingleVerKvEntry::SerializeCompressedDatas(const std::vector<SingleVerKvEntry *> &kvEntries,
428 const std::vector<uint8_t> &compressedEntries, Parcel &parcel, uint32_t targetVersion, CompressAlgorithm algo)
429 {
430 uint32_t srcLen = CalculateLens(kvEntries, targetVersion);
431 (void)parcel.WriteUInt32(static_cast<uint32_t>(algo));
432 (void)parcel.WriteUInt32(srcLen);
433 (void)parcel.WriteVector(compressedEntries);
434 return parcel.IsError() ? -E_PARSE_FAIL : E_OK;
435 }
436
DeSerializeCompressedDatas(std::vector<SingleVerKvEntry * > & kvEntries,Parcel & parcel)437 int GenericSingleVerKvEntry::DeSerializeCompressedDatas(std::vector<SingleVerKvEntry *> &kvEntries, Parcel &parcel)
438 {
439 // Get compression algo type.
440 uint32_t algoType = 0;
441 (void)parcel.ReadUInt32(algoType);
442 CompressAlgorithm compressAlgo = CompressAlgorithm::NONE;
443 int errCode = DataCompression::TransferCompressionAlgo(algoType, compressAlgo);
444 if (errCode != E_OK) {
445 return errCode;
446 }
447
448 // Get buffer length.
449 uint32_t destLen = 0;
450 (void)parcel.ReadUInt32(destLen);
451
452 // Get compressed data.
453 std::vector<uint8_t> srcData;
454 (void)parcel.ReadVector(srcData);
455 if (parcel.IsError()) {
456 return -E_PARSE_FAIL;
457 }
458
459 // Uncompress data.
460 return GenericSingleVerKvEntry::Uncompress(srcData, kvEntries, destLen, compressAlgo);
461 }
462 } // namespace DistributedDB
463