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