• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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