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 return AdaptToVersion(OperType::SERIALIZE, targetVersion, parcel, len);
122 }
123
SerializeDatas(const std::vector<SingleVerKvEntry * > & kvEntries,Parcel & parcel,uint32_t targetVersion)124 int GenericSingleVerKvEntry::SerializeDatas(const std::vector<SingleVerKvEntry *> &kvEntries, Parcel &parcel,
125 uint32_t targetVersion)
126 {
127 uint32_t size = static_cast<uint32_t>(kvEntries.size());
128 int errCode = parcel.WriteUInt32(size);
129 if (errCode != E_OK) {
130 LOGE("[SerializeDatas] write entries size failed, errCode=%d.", errCode);
131 return errCode;
132 }
133 parcel.EightByteAlign();
134 if (parcel.IsError()) {
135 return -E_PARSE_FAIL;
136 }
137 for (const auto &kvEntry : kvEntries) {
138 if (kvEntry == nullptr) {
139 continue;
140 }
141 errCode = kvEntry->SerializeData(parcel, targetVersion);
142 if (errCode != E_OK) {
143 LOGE("[SerializeDatas] write kvEntry failed, errCode=%d.", errCode);
144 return errCode;
145 }
146 }
147 return errCode;
148 }
149
150 // this func should do compatible
CalculateLen(uint32_t targetVersion)151 uint32_t GenericSingleVerKvEntry::CalculateLen(uint32_t targetVersion)
152 {
153 uint64_t len = 0;
154 int errCode = AdaptToVersion(OperType::CAL_LEN, targetVersion, len);
155 if ((len > INT32_MAX) || (errCode != E_OK)) {
156 return 0;
157 }
158 return len;
159 }
160
CalculateLens(const std::vector<SingleVerKvEntry * > & kvEntries,uint32_t targetVersion)161 uint32_t GenericSingleVerKvEntry::CalculateLens(const std::vector<SingleVerKvEntry *> &kvEntries,
162 uint32_t targetVersion)
163 {
164 uint64_t len = 0;
165 len += Parcel::GetUInt32Len();
166 len = BYTE_8_ALIGN(len);
167 for (const auto &kvEntry : kvEntries) {
168 if (kvEntry == nullptr) {
169 continue;
170 }
171 len += kvEntry->CalculateLen(targetVersion);
172 if (len > INT32_MAX) {
173 return 0;
174 }
175 }
176 return len;
177 }
178
179 // this func should do compatible
DeSerializeData(Parcel & parcel)180 int GenericSingleVerKvEntry::DeSerializeData(Parcel &parcel)
181 {
182 uint32_t version = VERSION_INVALID;
183 uint64_t len = parcel.ReadUInt32(version);
184 if (parcel.IsError()) {
185 return 0;
186 }
187 int errCode = AdaptToVersion(OperType::DESERIALIZE, version, parcel, len);
188 if (errCode != E_OK) {
189 len = 0;
190 }
191 return len;
192 }
193
DeSerializeDatas(std::vector<SingleVerKvEntry * > & kvEntries,Parcel & parcel)194 int GenericSingleVerKvEntry::DeSerializeDatas(std::vector<SingleVerKvEntry *> &kvEntries, Parcel &parcel)
195 {
196 uint32_t size = 0;
197 uint64_t len = parcel.ReadUInt32(size);
198 if (size > DBConstant::MAX_NORMAL_PACK_ITEM_SIZE) {
199 return 0;
200 }
201 parcel.EightByteAlign();
202 if (parcel.IsError()) {
203 return 0;
204 }
205 len = BYTE_8_ALIGN(len);
206 for (uint32_t i = 0; i < size; i++) {
207 auto kvEntry = new (std::nothrow) GenericSingleVerKvEntry();
208 if (kvEntry == nullptr) {
209 LOGE("Create kvEntry failed.");
210 len = 0;
211 break;
212 }
213 len += kvEntry->DeSerializeData(parcel);
214 kvEntries.push_back(kvEntry);
215 if (len > INT32_MAX || parcel.IsError()) {
216 len = 0;
217 break;
218 }
219 }
220 if (len == 0) {
221 for (auto &kvEntry : kvEntries) {
222 delete kvEntry;
223 kvEntry = nullptr;
224 }
225 }
226 return len;
227 }
228
AdaptToVersion(OperType operType,uint32_t targetVersion,Parcel & parcel,uint64_t & dataLen)229 int GenericSingleVerKvEntry::AdaptToVersion(OperType operType, uint32_t targetVersion, Parcel &parcel,
230 uint64_t &dataLen)
231 {
232 if (targetVersion < SOFTWARE_VERSION_EARLIEST || targetVersion > SOFTWARE_VERSION_CURRENT) {
233 return -E_VERSION_NOT_SUPPORT;
234 }
235 int errCode = E_OK;
236 switch (operType) {
237 case OperType::SERIALIZE:
238 errCode = SerializeDataByVersion(targetVersion, parcel);
239 break;
240 case OperType::DESERIALIZE:
241 errCode = DeSerializeByVersion(targetVersion, parcel, dataLen);
242 break;
243 default:
244 LOGE("Unknown upgrade serialize oper!");
245 return -E_UPGRADE_FAILED;
246 }
247 return errCode;
248 }
249
AdaptToVersion(OperType operType,uint32_t targetVersion,uint64_t & dataLen)250 int GenericSingleVerKvEntry::AdaptToVersion(OperType operType, uint32_t targetVersion, uint64_t &dataLen)
251 {
252 if (targetVersion < SOFTWARE_VERSION_EARLIEST || targetVersion > SOFTWARE_VERSION_CURRENT) {
253 return -E_VERSION_NOT_SUPPORT;
254 }
255
256 if (operType == OperType::CAL_LEN) {
257 return CalLenByVersion(targetVersion, dataLen);
258 } else {
259 LOGE("Unknown upgrade serialize oper!");
260 return -E_UPGRADE_FAILED;
261 }
262 }
263
SerializeDataByFirstVersion(Parcel & parcel) const264 int GenericSingleVerKvEntry::SerializeDataByFirstVersion(Parcel &parcel) const
265 {
266 (void)parcel.WriteVectorChar(dataItem_.key);
267 (void)parcel.WriteVectorChar(dataItem_.value);
268 (void)parcel.WriteUInt64(dataItem_.timestamp);
269 (void)parcel.WriteUInt64(dataItem_.flag);
270
271 return parcel.WriteString(dataItem_.origDev);
272 }
273
SerializeDataByLaterVersion(Parcel & parcel,uint32_t targetVersion) const274 int GenericSingleVerKvEntry::SerializeDataByLaterVersion(Parcel &parcel, uint32_t targetVersion) const
275 {
276 Timestamp writeTimestamp = dataItem_.writeTimestamp;
277 if (writeTimestamp == 0) {
278 writeTimestamp = dataItem_.timestamp;
279 }
280 int errCode = parcel.WriteUInt64(writeTimestamp);
281 if (errCode != E_OK) {
282 return errCode;
283 }
284 if (targetVersion >= SOFTWARE_VERSION_RELEASE_6_0) {
285 errCode = parcel.WriteVector(dataItem_.hashKey);
286 }
287 return errCode;
288 }
289
SerializeDataByVersion(uint32_t targetVersion,Parcel & parcel) const290 int GenericSingleVerKvEntry::SerializeDataByVersion(uint32_t targetVersion, Parcel &parcel) const
291 {
292 int errCode = SerializeDataByFirstVersion(parcel);
293 if (targetVersion == SOFTWARE_VERSION_EARLIEST || errCode != E_OK) {
294 return errCode;
295 }
296 return SerializeDataByLaterVersion(parcel, targetVersion);
297 }
298
CalLenByFirstVersion(uint64_t & len) const299 void GenericSingleVerKvEntry::CalLenByFirstVersion(uint64_t &len) const
300 {
301 len += Parcel::GetUInt32Len();
302 len += Parcel::GetVectorCharLen(dataItem_.key);
303 len += Parcel::GetVectorCharLen(dataItem_.value);
304 len += Parcel::GetUInt64Len();
305 len += Parcel::GetUInt64Len();
306 len += Parcel::GetStringLen(dataItem_.origDev);
307 }
308
CalLenByLaterVersion(uint64_t & len,uint32_t targetVersion) const309 void GenericSingleVerKvEntry::CalLenByLaterVersion(uint64_t &len, uint32_t targetVersion) const
310 {
311 len += Parcel::GetUInt64Len();
312 if (targetVersion >= SOFTWARE_VERSION_RELEASE_6_0) {
313 len += Parcel::GetVectorLen(dataItem_.hashKey);
314 }
315 }
316
CalLenByVersion(uint32_t targetVersion,uint64_t & len) const317 int GenericSingleVerKvEntry::CalLenByVersion(uint32_t targetVersion, uint64_t &len) const
318 {
319 CalLenByFirstVersion(len);
320 if (targetVersion == SOFTWARE_VERSION_EARLIEST) {
321 return E_OK;
322 }
323 CalLenByLaterVersion(len, targetVersion);
324 return E_OK;
325 }
326
DeSerializeByFirstVersion(uint64_t & len,Parcel & parcel)327 void GenericSingleVerKvEntry::DeSerializeByFirstVersion(uint64_t &len, Parcel &parcel)
328 {
329 len += parcel.ReadVectorChar(dataItem_.key);
330 len += parcel.ReadVectorChar(dataItem_.value);
331 len += parcel.ReadUInt64(dataItem_.timestamp);
332 len += parcel.ReadUInt64(dataItem_.flag);
333 len += parcel.ReadString(dataItem_.origDev);
334 dataItem_.writeTimestamp = dataItem_.timestamp;
335 }
336
DeSerializeByLaterVersion(uint64_t & len,Parcel & parcel,uint32_t targetVersion)337 void GenericSingleVerKvEntry::DeSerializeByLaterVersion(uint64_t &len, Parcel &parcel, uint32_t targetVersion)
338 {
339 len += parcel.ReadUInt64(dataItem_.writeTimestamp);
340 if (targetVersion >= SOFTWARE_VERSION_RELEASE_6_0) {
341 len += parcel.ReadVector(dataItem_.hashKey);
342 }
343 }
344
DeSerializeByVersion(uint32_t targetVersion,Parcel & parcel,uint64_t & len)345 int GenericSingleVerKvEntry::DeSerializeByVersion(uint32_t targetVersion, Parcel &parcel, uint64_t &len)
346 {
347 DeSerializeByFirstVersion(len, parcel);
348 if (targetVersion == SOFTWARE_VERSION_EARLIEST) {
349 return E_OK;
350 }
351 DeSerializeByLaterVersion(len, parcel, targetVersion);
352 return E_OK;
353 }
354
CalculateCompressedLens(const std::vector<uint8_t> & compressedData)355 uint32_t GenericSingleVerKvEntry::CalculateCompressedLens(const std::vector<uint8_t> &compressedData)
356 {
357 // No compressed data in sync.
358 if (compressedData.empty()) {
359 return 0;
360 }
361
362 // Calculate compressed data length.
363 uint64_t len = 0;
364 len += Parcel::GetUInt32Len(); // srcLen.
365 len += Parcel::GetUInt32Len(); // compression algorithm type.
366 len += Parcel::GetVectorLen(compressedData); // compressed data.
367 return (len > INT32_MAX) ? 0 : len;
368 }
369
Compress(const std::vector<SingleVerKvEntry * > & kvEntries,std::vector<uint8_t> & destData,const CompressInfo & compressInfo)370 int GenericSingleVerKvEntry::Compress(const std::vector<SingleVerKvEntry *> &kvEntries, std::vector<uint8_t> &destData,
371 const CompressInfo &compressInfo)
372 {
373 // Calculate length.
374 auto srcLen = CalculateLens(kvEntries, compressInfo.targetVersion);
375 if (srcLen == 0) {
376 LOGE("Over limit size, cannot compress.");
377 return -E_INVALID_ARGS;
378 }
379
380 // Serialize data.
381 std::vector<uint8_t> srcData(srcLen, 0);
382 Parcel parcel(srcData.data(), srcData.size());
383 int errCode = SerializeDatas(kvEntries, parcel, compressInfo.targetVersion);
384 if (errCode != E_OK) {
385 return errCode;
386 }
387
388 // Compress data.
389 auto inst = DataCompression::GetInstance(compressInfo.compressAlgo);
390 if (inst == nullptr) {
391 return -E_INVALID_COMPRESS_ALGO;
392 }
393 return inst->Compress(srcData, destData);
394 }
395
Uncompress(const std::vector<uint8_t> & srcData,std::vector<SingleVerKvEntry * > & kvEntries,uint32_t destLen,CompressAlgorithm algo)396 int GenericSingleVerKvEntry::Uncompress(const std::vector<uint8_t> &srcData, std::vector<SingleVerKvEntry *> &kvEntries,
397 uint32_t destLen, CompressAlgorithm algo)
398 {
399 // Uncompress data.
400 std::vector<uint8_t> destData(destLen, 0);
401 auto inst = DataCompression::GetInstance(algo);
402 if (inst == nullptr) {
403 return -E_INVALID_COMPRESS_ALGO;
404 }
405 int errCode = inst->Uncompress(srcData, destData, destLen);
406 if (errCode != E_OK) {
407 return errCode;
408 }
409
410 // Deserialize data.
411 Parcel parcel(destData.data(), destData.size());
412 if (DeSerializeDatas(kvEntries, parcel) == 0) {
413 return -E_PARSE_FAIL;
414 }
415 return E_OK;
416 }
417
SerializeCompressedDatas(const std::vector<SingleVerKvEntry * > & kvEntries,const std::vector<uint8_t> & compressedEntries,Parcel & parcel,uint32_t targetVersion,CompressAlgorithm algo)418 int GenericSingleVerKvEntry::SerializeCompressedDatas(const std::vector<SingleVerKvEntry *> &kvEntries,
419 const std::vector<uint8_t> &compressedEntries, Parcel &parcel, uint32_t targetVersion, CompressAlgorithm algo)
420 {
421 uint32_t srcLen = CalculateLens(kvEntries, targetVersion);
422 (void)parcel.WriteUInt32(static_cast<uint32_t>(algo));
423 (void)parcel.WriteUInt32(srcLen);
424 (void)parcel.WriteVector(compressedEntries);
425 return parcel.IsError() ? -E_PARSE_FAIL : E_OK;
426 }
427
DeSerializeCompressedDatas(std::vector<SingleVerKvEntry * > & kvEntries,Parcel & parcel)428 int GenericSingleVerKvEntry::DeSerializeCompressedDatas(std::vector<SingleVerKvEntry *> &kvEntries, Parcel &parcel)
429 {
430 // Get compression algo type.
431 uint32_t algoType = 0;
432 (void)parcel.ReadUInt32(algoType);
433 CompressAlgorithm compressAlgo = CompressAlgorithm::NONE;
434 int errCode = DataCompression::TransferCompressionAlgo(algoType, compressAlgo);
435 if (errCode != E_OK) {
436 return errCode;
437 }
438
439 // Get buffer length.
440 uint32_t destLen = 0;
441 (void)parcel.ReadUInt32(destLen);
442 if (destLen > DBConstant::MAX_SYNC_BLOCK_SIZE) {
443 LOGE("[GenericSingleVerKvEntry] Invalid compress data len %" PRIu32, destLen);
444 return -E_INVALID_ARGS;
445 }
446
447 // Get compressed data.
448 std::vector<uint8_t> srcData;
449 (void)parcel.ReadVector(srcData);
450 if (parcel.IsError()) {
451 return -E_PARSE_FAIL;
452 }
453
454 // Uncompress data.
455 return GenericSingleVerKvEntry::Uncompress(srcData, kvEntries, destLen, compressAlgo);
456 }
457 } // namespace DistributedDB
458