• 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     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