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