浅析avro序列化和反序列化源码及提供两种数据序列存储思路

2023-12-20 13:50

本文主要是介绍浅析avro序列化和反序列化源码及提供两种数据序列存储思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以hadoop的avro实现原理做引子:

varo的测试样例程序

#include <complex>#include "avro/Encoder.hh"
#include "avro/Decoder.hh"
#include "avro/Specific.hh"namespace avro {
template<typename T>
struct codec_traits<std::complex<T> > {static void encode(Encoder& e, const std::complex<T>& c) {avro::encode(e, std::real(c));avro::encode(e, std::imag(c));}static void decode(Decoder& d, std::complex<T>& c) {T re, im;avro::decode(d, re);avro::decode(d, im);c = std::complex<T>(re, im);}
};}
int
main()
{std::auto_ptr<avro::OutputStream> out = avro::memoryOutputStream();avro::EncoderPtr e = avro::binaryEncoder();e->init(*out);std::complex<double> c1(1.0, 2.0);avro::encode(*e, c1);std::auto_ptr<avro::InputStream> in = avro::memoryInputStream(*out);avro::DecoderPtr d = avro::binaryDecoder();d->init(*in);std::complex<double> c2;avro::decode(*d, c2);std::cout << '(' << std::real(c2) << ", " << std::imag(c2) << ')' << std::endl;return 0;
}

这个样例相对简单。

其中template <typename T>

    struct codec_traits {  };  

为avro对不同数据类型存储实现的模板类特化。

由于avro的基础库类未有提供std::complex<double>的特化说明,故在样例函数添加avro作用域的complex类型说明,并将复数类型的特化函数转化为avro提供的基础数据类型的特化

特化函数定义在avro  api/specific.hh 头文件中定义。样例这里使用了 143行定义的double类型处理

template <> struct codec_traits<double> {
    /**
     * Encodes a given value.
     */
    static void encode(Encoder& e, double d) {
        e.encodeDouble(d);
    }
    /**
     * Decodes into a given value.
     */
    static void decode(Decoder& d, double& dbl) {
        dbl = d.decodeDouble();
    }

};

这里说明下avro内部存储数据的结构:

由于样例中使用的是 二进制编制的内存存储形式(相对于文件存储)

std::auto_ptr<avro::OutputStream> out = avro::memoryOutputStream();

avro::EncoderPtr e = avro::binaryEncoder();

其中 :memoryOutputStream 数据保存内存存储类

           binaryEncoder  存储数据写入管理类  --- 对应Impl/binaryEncoder.cc文件

double写入内存函数实现:

void BinaryEncoder::encodeDouble(double d)
{
    const uint8_t* p = reinterpret_cast<const uint8_t*>(&d);
    out_.writeBytes(p, sizeof(double));
}

out为MemoryOutputStream管理类。对应文件实现impl/stream.cc 文件

其存储形式如下图。如上例中c1(1.0,2.0)。其中图示每一个方格为一个double存储单元。


写入逻辑实现为:

1.检测当前空间,如上图中一行是否足够double写入(注每次申请行为固定个数double存储单元)。否申请新的空间(即如上  图一行)

2.写入double数据,并记录当前写入地址及最大可写入地址。

以上为数据写入的实现,反之取出,只需要按顺序读取数值出来即可。

难点:avro特化函数对指定数据类型的处理


另外提供两种序列化和反序列化实现:

第一种:来自哥们写的。特复杂也很难理解,(我也看了好几天才懂~~),仅给出部分关键文件源码。

想看完整源码 可在github下载 :https://github.com/xyz347/x2struct

以json序列化为例源码示例:

X2Struct.hh  这个文件是关键,以宏遍历的形式对结构体成员进行逐个成员展开处理。如果想实现非json存储数据类型的数据序列化和反序列化也以这个文件为基础构建。

特别注意:结构体成员展开为二层次展开,(怎么理解,看代码~~~~)。结构体成员最大展开个数为 32*32


#ifndef __X_TO_STRUCT_HPP
#define __X_TO_STRUCT_HPP#include <string>
#include <set>
#include <stdexcept>
#include "xobj.hpp"#include "xmlstr.hpp"
#include "jsoncfgstr.hpp"#ifdef XTOSTRUCT_GEN_GOLANG_CODE
#include <typeinfo>
#include "gostr.hpp"
#endif
//#include <iostream>
//using namespace std;namespace x2struct {#define X2STRUCT_OPT_ME     "me"    // must existclass X {
public:template <typename TYPE>static bool loadjson(const std::string&str, TYPE&t, bool isfile=true) {JsonObj obj(str, isfile);t.__x_to_struct(obj);return true;}   template <typename TYPE>static std::string tojson(const TYPE&t, const std::string&root, bool newline=true, int space=4) {JsonCfgStr obj(true, newline, space);t.__struct_to_str(obj, root, 0);return obj.toStr();}};#define X_STRUCT_FUNC_TOX_BEGIN                                             \
private:                                                                    \std::set<std::string> __x_has_string;                                   \
public:                                                                     \bool xhas(const std::string& name) const {                              \return __x_has_string.find(name)!=__x_has_string.end();             \}                                                                       \bool __x_condition(x2struct::XObj& obj, const std::string&name) {       \(void)obj;(void)name;                                               \return true;                                                        \}                                                                       \void __x_to_struct(x2struct::XObj& obj) {#define X_STRUCT_ACT_TOX_O(M)                                               \if (obj.has(#M)) {                                                  \obj[#M].convert(M);                                             \__x_has_string.insert(#M);                                      \}#define X_STRUCT_ACT_TOX_M(M)                                               \if (obj.has(#M)) {                                                  \obj[#M].convert(M);                                             \__x_has_string.insert(#M);                                      \} else {                                                            \obj.me_exception(#M);                                           \}// aliase name
#define X_STRUCT_ACT_TOX_A(M, A_NAME)                                       \{                                                                       \bool me = false;                                                    \std::string __alias__name__ = obj.hasa(#M, A_NAME, me);             \if (!__alias__name__.empty()) {                                     \obj[__alias__name__].convert(M);                                \__x_has_string.insert(#M);                                      \} else if (me) {                                                    \obj.me_exception(#M);                                           \}                                                                   \}#define X_STRUCT_FUNC_TOX_END }// struct to string
#define X_STRUCT_FUNC_TOS_BEGIN                                                     \template <class CLASS>                                                          \void __struct_to_str(CLASS& obj, const std::string&root, int splen) const {     \int index = 0;                                                              \obj.begin(root, splen);#define X_STRUCT_ACT_TOS_O(M)                                                       \obj.convert(#M, M, splen+obj.space(), index++);#define X_STRUCT_ACT_TOS_A(M, A_NAME)                                               \obj.convert(obj.fieldName(#M,A_NAME), M, splen+obj.space(), index++);#define X_STRUCT_FUNC_TOS_END                                                       \obj.end(root,splen);                                                        \}// struct to golang code
#define X_STRUCT_FUNC_TOG_BEGIN                                                     \std::string __struct_to_go(x2struct::GoCode &obj) const {                       \obj.set_type_id_name(typeid(*this).name());#define X_STRUCT_ACT_TOG_O(M)                                                       \obj.convert(M, #M);#define X_STRUCT_ACT_TOG_A(M, A_NAME)                                               \obj.convert(M, #M, A_NAME);#define X_STRUCT_FUNC_TOG_END                                                       \return obj.str();                                                           \}// lenght should equal X_STRUCT_N
#define X_DEC_LIST _32,_31,_30,_29,_28,_27,_26,_25,_24,_23,_22,_21,_20,_19,_18,_17,_16,_15,_14,_13,_12,_11,_10,_9,_8,_7,_6,_5,_4,_3,_2,_1
// expand macro depend on parameters number
#define X_STRUCT_N(ACTION,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,N,...) ACTION##N/*work with X_STRUCT_N to expand macrostruct MyX {int         a;std::string b;double      c;XTOSTRUCT(A(a,"_id"), O(b,c));};there'r two layer in this macro:l1: A(a,"_id"), O(b,c)l2: a,"_id"; b,cso we need expand twice
*/// wrap X_STRUCT_N. so we can use X_DEC_LIST
#define X_STRUCT_WRAP_L1(ACT, LIST, ...) X_STRUCT_N(X_STRUCT_L1, __VA_ARGS__, LIST)(ACT, __VA_ARGS__)
#define X_STRUCT_WRAP_L2(ACT, LIST, ...) X_STRUCT_N(X_STRUCT_L2, __VA_ARGS__, LIST)(ACT, __VA_ARGS__)#define X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_##ACT##M
#define X_STRUCT_L1_1(ACT, M)        X_STRUCT_L1_DEF(ACT, M)
#define X_STRUCT_L1_2(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_1(ACT, __VA_ARGS__)
#define X_STRUCT_L1_3(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_2(ACT, __VA_ARGS__)
#define X_STRUCT_L1_4(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_3(ACT, __VA_ARGS__)
#define X_STRUCT_L1_5(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_4(ACT, __VA_ARGS__)
#define X_STRUCT_L1_6(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_5(ACT, __VA_ARGS__)
#define X_STRUCT_L1_7(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_6(ACT, __VA_ARGS__)
#define X_STRUCT_L1_8(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_7(ACT, __VA_ARGS__)
#define X_STRUCT_L1_9(ACT, M,...)    X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_8(ACT, __VA_ARGS__)
#define X_STRUCT_L1_10(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_9(ACT, __VA_ARGS__)
#define X_STRUCT_L1_11(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_10(ACT, __VA_ARGS__)
#define X_STRUCT_L1_12(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_11(ACT, __VA_ARGS__)
#define X_STRUCT_L1_13(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_12(ACT, __VA_ARGS__)
#define X_STRUCT_L1_14(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_13(ACT, __VA_ARGS__)
#define X_STRUCT_L1_15(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_14(ACT, __VA_ARGS__)
#define X_STRUCT_L1_16(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_15(ACT, __VA_ARGS__)
#define X_STRUCT_L1_17(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_16(ACT, __VA_ARGS__)
#define X_STRUCT_L1_18(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_17(ACT, __VA_ARGS__)
#define X_STRUCT_L1_19(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_18(ACT, __VA_ARGS__)
#define X_STRUCT_L1_20(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_19(ACT, __VA_ARGS__)
#define X_STRUCT_L1_21(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_20(ACT, __VA_ARGS__)
#define X_STRUCT_L1_22(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_21(ACT, __VA_ARGS__)
#define X_STRUCT_L1_23(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_22(ACT, __VA_ARGS__)
#define X_STRUCT_L1_24(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_23(ACT, __VA_ARGS__)
#define X_STRUCT_L1_25(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_24(ACT, __VA_ARGS__)
#define X_STRUCT_L1_26(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_25(ACT, __VA_ARGS__)
#define X_STRUCT_L1_27(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_26(ACT, __VA_ARGS__)
#define X_STRUCT_L1_28(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_27(ACT, __VA_ARGS__)
#define X_STRUCT_L1_29(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_28(ACT, __VA_ARGS__)
#define X_STRUCT_L1_30(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_29(ACT, __VA_ARGS__)
#define X_STRUCT_L1_31(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_30(ACT, __VA_ARGS__)
#define X_STRUCT_L1_32(ACT, M,...)   X_STRUCT_L1_DEF(ACT, M)      X_STRUCT_L1_31(ACT, __VA_ARGS__)#define X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_ACT_##ACT(M)
#define X_STRUCT_L2_1(ACT, M)       X_STRUCT_L2_DEF(ACT, M)
#define X_STRUCT_L2_2(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_1(ACT, __VA_ARGS__)
#define X_STRUCT_L2_3(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_2(ACT, __VA_ARGS__)
#define X_STRUCT_L2_4(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_3(ACT, __VA_ARGS__)
#define X_STRUCT_L2_5(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_4(ACT, __VA_ARGS__)
#define X_STRUCT_L2_6(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_5(ACT, __VA_ARGS__)
#define X_STRUCT_L2_7(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_6(ACT, __VA_ARGS__)
#define X_STRUCT_L2_8(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_7(ACT, __VA_ARGS__)
#define X_STRUCT_L2_9(ACT, M,...)   X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_8(ACT, __VA_ARGS__)
#define X_STRUCT_L2_10(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_9(ACT, __VA_ARGS__)
#define X_STRUCT_L2_11(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_10(ACT, __VA_ARGS__)
#define X_STRUCT_L2_12(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_11(ACT, __VA_ARGS__)
#define X_STRUCT_L2_13(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_12(ACT, __VA_ARGS__)
#define X_STRUCT_L2_14(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_13(ACT, __VA_ARGS__)
#define X_STRUCT_L2_15(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_14(ACT, __VA_ARGS__)
#define X_STRUCT_L2_16(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_15(ACT, __VA_ARGS__)
#define X_STRUCT_L2_17(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_16(ACT, __VA_ARGS__)
#define X_STRUCT_L2_18(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_17(ACT, __VA_ARGS__)
#define X_STRUCT_L2_19(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_18(ACT, __VA_ARGS__)
#define X_STRUCT_L2_20(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_19(ACT, __VA_ARGS__)
#define X_STRUCT_L2_21(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_20(ACT, __VA_ARGS__)
#define X_STRUCT_L2_22(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_21(ACT, __VA_ARGS__)
#define X_STRUCT_L2_23(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_22(ACT, __VA_ARGS__)
#define X_STRUCT_L2_24(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_23(ACT, __VA_ARGS__)
#define X_STRUCT_L2_25(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_24(ACT, __VA_ARGS__)
#define X_STRUCT_L2_26(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_25(ACT, __VA_ARGS__)
#define X_STRUCT_L2_27(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_26(ACT, __VA_ARGS__)
#define X_STRUCT_L2_28(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_27(ACT, __VA_ARGS__)
#define X_STRUCT_L2_29(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_28(ACT, __VA_ARGS__)
#define X_STRUCT_L2_30(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_29(ACT, __VA_ARGS__)
#define X_STRUCT_L2_31(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_30(ACT, __VA_ARGS__)
#define X_STRUCT_L2_32(ACT, M,...)  X_STRUCT_L2_DEF(ACT, M)     X_STRUCT_L2_31(ACT, __VA_ARGS__)// L1 action define. O M A
// string to struct
#define X_STRUCT_L1_TOX_O(...)  X_STRUCT_WRAP_L2(TOX_O, X_DEC_LIST, __VA_ARGS__)
#define X_STRUCT_L1_TOX_M(...)  X_STRUCT_WRAP_L2(TOX_M, X_DEC_LIST, __VA_ARGS__)
#define X_STRUCT_L1_TOX_A(M,A)  X_STRUCT_ACT_TOX_A(M,A)// struct to string
#define X_STRUCT_L1_TOS_O(...)  X_STRUCT_WRAP_L2(TOS_O, X_DEC_LIST, __VA_ARGS__)
#define X_STRUCT_L1_TOS_M       X_STRUCT_L1_TOS_O
#define X_STRUCT_L1_TOS_A(M,A)  X_STRUCT_ACT_TOS_A(M,A)// struct to golang code
#define X_STRUCT_L1_TOG_O(...)  X_STRUCT_WRAP_L2(TOG_O, X_DEC_LIST, __VA_ARGS__)
#define X_STRUCT_L1_TOG_M       X_STRUCT_L1_TOG_O
#define X_STRUCT_L1_TOG_A(M,A)  X_STRUCT_ACT_TOG_A(M,A)#ifdef XTOSTRUCT_GEN_GOLANG_CODE
#define XTOSTRUCT(...)  \X_STRUCT_FUNC_TOX_BEGIN  X_STRUCT_WRAP_L1(TOX_, X_DEC_LIST, __VA_ARGS__) X_STRUCT_FUNC_TOX_END  \X_STRUCT_FUNC_TOS_BEGIN  X_STRUCT_WRAP_L1(TOS_, X_DEC_LIST, __VA_ARGS__) X_STRUCT_FUNC_TOS_END  \X_STRUCT_FUNC_TOG_BEGIN  X_STRUCT_WRAP_L1(TOG_, X_DEC_LIST, __VA_ARGS__) X_STRUCT_FUNC_TOG_END
#else
#define XTOSTRUCT(...)  \X_STRUCT_FUNC_TOX_BEGIN  X_STRUCT_WRAP_L1(TOX_, X_DEC_LIST, __VA_ARGS__) X_STRUCT_FUNC_TOX_END  \X_STRUCT_FUNC_TOS_BEGIN  X_STRUCT_WRAP_L1(TOS_, X_DEC_LIST, __VA_ARGS__) X_STRUCT_FUNC_TOS_END
#endif#define XTOSTRUCT_CONDITION()   bool __x_condition(x2struct::XObj& obj, const char* name)
#define XTOSTRUCT_CONDITION_EQ(attr1, attr2)                    \bool __x_condition(x2struct::XObj& obj, const char* name) { \return obj.attribute(attr1)==obj.attribute(attr2);      \}}#endif

jsonstrcfg.h  json序列化和反序列化接口定义


* Copyright (C) 2017 YY Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at
*
*	http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, 
* software distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*/#ifndef __X_TO_STRUCT_JSON_CFG_STR_HPP
#define __X_TO_STRUCT_JSON_CFG_STR_HPP#include <stdint.h>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <sstream>
#include <boost/lexical_cast.hpp>#include "xstr.hpp"namespace x2struct {class JsonCfgStr:public XStr {
public:JsonCfgStr(bool isjson, bool newline=false, int splen=4);~JsonCfgStr();
public:void begin(const std::string&root, int splen);void end(const std::string&root, int splen);int  space();std::string toStr() const;
public:virtual void convert(const std::string&name, const std::string& data, int space, int index);// base typevoid convert(const std::string&name, int16_t data, int splen, int index);void convert(const std::string&name, uint16_t data, int splen, int index);void convert(const std::string&name, int32_t data, int splen, int index);void convert(const std::string&name, uint32_t data, int splen, int index);void convert(const std::string&name, int64_t data, int splen, int index);void convert(const std::string&name, uint64_t data, int splen, int index);void convert(const std::string&name, float data, int splen, int index);void convert(const std::string&name, double data, int splen, int index);void convert(const std::string&name, bool data, int splen, int index);// base type vectorvoid convert(const std::string&name, const std::vector<int16_t>& data, int splen, int index);void convert(const std::string&name, const std::vector<uint16_t>& data, int splen, int index);void convert(const std::string&name, const std::vector<int32_t>& data, int splen, int index);void convert(const std::string&name, const std::vector<uint32_t>& data, int splen, int index);void convert(const std::string&name, const std::vector<int64_t>& data, int splen, int index);void convert(const std::string&name, const std::vector<uint64_t>& data, int splen, int index);void convert(const std::string&name, const std::vector<float>& data, int splen, int index);void convert(const std::string&name, const std::vector<double>& data, int splen, int index);void convert(const std::string&name, const std::vector<bool>& data, int splen, int index);void convert(const std::string&name, const std::vector<std::string>& data, int splen, int index);// base type setvoid convert(const std::string&name, const std::set<int16_t>& data, int splen, int index);void convert(const std::string&name, const std::set<uint16_t>& data, int splen, int index);void convert(const std::string&name, const std::set<int32_t>& data, int splen, int index);void convert(const std::string&name, const std::set<uint32_t>& data, int splen, int index);void convert(const std::string&name, const std::set<int64_t>& data, int splen, int index);void convert(const std::string&name, const std::set<uint64_t>& data, int splen, int index);void convert(const std::string&name, const std::set<float>& data, int splen, int index);void convert(const std::string&name, const std::set<double>& data, int splen, int index);void convert(const std::string&name, const std::set<bool>& data, int splen, int index);void convert(const std::string&name, const std::set<std::string>& data, int splen, int index);template <typename TYPE>void convert(const std::string&name, const std::vector<TYPE> &data, int splen, int index) {linefeed(index);std::string oldsep(_sep);//_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;} else {_ss<<std::string(splen, ' ')<<_vecb;}for (size_t i=0; i<data.size(); ++i) {_sep=",";this->convert("", data[i], splen+space(), (int)i);_sep=oldsep;}_ss<<(_newline?"\n":"")<<std::string(splen, ' ')<<_vece;}template <typename TYPE>void convert(const std::string&name, const std::set<TYPE> &data, int splen, int index) {int i = 0;linefeed(index);std::string oldsep(_sep);//_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;} else {_ss<<std::string(splen, ' ')<<_vecb;}for (typename std::set<TYPE>::const_iterator it=data.begin(); it!=data.end(); ++it) {_sep=",";this->convert("", *it, splen+space(), i++);_sep=oldsep;}_ss<<(_newline?"\n":"")<<std::string(splen, ' ')<<_vece;}template <typename TYPE>void convert(const std::string&name, const std::map<std::string,TYPE> &data, int splen, int index) {int i = 0;linefeed(index);std::string oldsep(_sep);if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<"{";} else {_ss<<std::string(splen, ' ')<<"{";}for (typename std::map<std::string,TYPE>::const_iterator iter=data.begin(); iter!=data.end(); ++iter) {_sep=",";this->convert(iter->first, iter->second, splen+space(), i++);_sep=oldsep;}_ss<<(_newline?"\n":"")<<std::string(splen, ' ')<<"}";}template <typename KEYTYPE, typename TYPE>void convert(const std::string&name, const std::map<KEYTYPE, TYPE> &data, int splen, int index) {int i = 0;linefeed(index);std::string oldsep(_sep);if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<"{";} else {_ss<<std::string(splen, ' ')<<"{";}for (typename std::map<KEYTYPE,TYPE>::const_iterator iter=data.begin(); iter!=data.end(); ++iter) {_sep=",";std::string _k = boost::lexical_cast<std::string>(iter->first);this->convert(_k, iter->second, splen+space(), i++);_sep=oldsep;}_ss<<(_newline?"\n":"")<<std::string(splen, ' ')<<"}";}template <typename TYPE>void convert(const std::string&name, const TYPE& data, int splen, int index) {linefeed(index);data.__struct_to_str(*this, name, splen);}
private:void linefeed(int index) {if (index>0) {_ss<<_sep;}if (_newline) {_ss<<'\n';}}template <typename TYPE>void base_convert(const std::string&name, const TYPE& data, int splen, int index) {linefeed(index);if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<data;} else {_ss<<std::string(splen, ' ')<<data;}}template <typename TYPE>void base_vector(const std::string&name, const std::vector<TYPE>& data, int splen, int index) {linefeed(index);if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;} else {_ss<<std::string(splen, ' ')<<_vecb;}for (typename std::vector<TYPE>::const_iterator it=data.begin(); it!=data.end(); ++it) {if (it != data.begin()) {_ss<<',';}_ss<<*it;}_ss<<_vece;}template <typename TYPE>void base_set(const std::string&name, const std::set<TYPE>& data, int splen, int index) {linefeed(index);if (!name.empty()) {_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;} else {_ss<<std::string(splen, ' ')<<_vecb;}for (typename std::set<TYPE>::const_iterator it=data.begin(); it!=data.end(); ++it) {if (it != data.begin()) {_ss<<',';}_ss<<*it;}_ss<<_vece;}
private:bool _json;bool _newline;int  _space;std::string _vecb;  // json:[, cfg:(std::string _vece;  // json:], cfg:)std::string _key;   // json:", cfg:(empty)std::string _assign;// json::, cfg:=std::string _sep;   // json:,, cfg:;std::stringstream _ss;
};}#endif

jsonstrcfg.cpp json序列化反序列化定义


* Copyright (C) 2017 YY Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at
*
*	http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, 
* software distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*/#include <json/json.h>#include "jsoncfgstr.hpp"namespace x2struct {using namespace std;JsonCfgStr::JsonCfgStr(bool isjson, bool newline, int splen):XStr(isjson?"json":"config"),_json(isjson), _newline(newline),_space(splen)
{if (isjson) {_vecb = "[";_vece = "]";_key = "\"";_assign = ":";_sep = ",";} else {_vecb = "(";_vece = ")";_assign = "=";_sep = ";";}
}JsonCfgStr::~JsonCfgStr()
{
}void JsonCfgStr::begin(const string&root, int splen)
{if (root.empty()) {_ss<<string(splen, ' ')<<"{";} else {_ss<<string(splen, ' ')<<_key<<root<<_key<<_assign<<"{";}
}void JsonCfgStr::end(const string&root, int splen)
{if (_newline) {_ss<<'\n';}_ss<<string(splen, ' ')<<"}";
}int  JsonCfgStr::space()
{return _newline?_space:0;
}string JsonCfgStr::toStr()const 
{return _ss.str();
}void JsonCfgStr::convert(const string&name, int16_t data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const string&name, uint16_t data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const string&name, int32_t data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const string&name, uint32_t data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, int64_t data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, uint64_t data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, float data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, double data, int splen, int index)
{base_convert(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, bool data, int splen, int index)
{base_convert(name, data?"true":"false", splen, index);
}void JsonCfgStr::convert(const string&name, const string& data, int splen, int index)
{linefeed(index);if (_json) {_ss<<string(splen, ' ')<<_key<<name<<_key<<_assign<<Json::valueToQuotedString(data.c_str());} else {_ss<<string(splen, ' ')<<_key<<name<<_key<<_assign<<'"'<<data<<'"';}
}// base type vector
void JsonCfgStr::convert(const std::string&name, const std::vector<int16_t>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<uint16_t>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<int32_t>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<uint32_t>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<int64_t>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<uint64_t>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<float>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<double>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<bool>& data, int splen, int index)
{base_vector(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::vector<std::string>& data, int splen, int index)
{linefeed(index);_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;for (typename std::vector<std::string>::const_iterator it=data.begin(); it!=data.end(); ++it) {if (it != data.begin()) {_ss<<',';}_ss<<'"'<<*it<<'"';}_ss<<_vece;
}// base type set
void JsonCfgStr::convert(const std::string&name, const std::set<int16_t>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<uint16_t>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<int32_t>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<uint32_t>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<int64_t>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<uint64_t>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<float>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<double>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<bool>& data, int splen, int index)
{base_set(name, data, splen, index);
}void JsonCfgStr::convert(const std::string&name, const std::set<std::string>& data, int splen, int index)
{linefeed(index);_ss<<std::string(splen, ' ')<<_key<<name<<_key<<_assign<<_vecb;for (typename std::set<std::string>::const_iterator it=data.begin(); it!=data.end(); ++it) {if (it != data.begin()) {_ss<<',';}_ss<<'"'<<*it<<'"';}_ss<<_vece;
}
}

第二种。实际上没做序列化定义,支撑任意类型的快速写入和取出,尤其应用在于单生产者、单消费者线程的无锁共享。怎么把它改造成rpc形式的序列化和反序列化,甚至支撑任意类型存储。可以使用avro特化函数。也可以借用redis队列协议即(数据类型+数据)。只是给个引子,怎么实现各位可以自己思考

.h

#ifndef __LOGBLOCKMANER_H__
#define __LOGBLOCKMANER_H__#include <stdio.h>
class LogBlockManer
{
public:~LogBlockManer(){}LogBlockManer(){_blockSize = 1;}
private:struct __BlockNode{int seq;int w_offset;int r_offset;int memsize;char * memory;struct __BlockNode * next;__BlockNode(){seq = 0;w_offset = 0;r_offset = 0;memsize  = 0;memory = NULL;next = NULL;}void reset(int size){w_offset = 0;r_offset = 0;memsize  = size;	next = NULL;return ;}};__BlockNode * _wrnode;__BlockNode * _rdnode;__BlockNode * _head;int           _blockSize;int           _threadmem;
public:int Init();int  writeLog(char * log,int size,__FileInfo *&file);bool readLog(char *& log,int &size,__FileInfo *&file);int  setThreadmemsize(int size);
};#endif
.cpp
#include "LogBlockManer.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MEMSIZE 1024*1024int LogBlockManer::writeLog(char * log,int size,__FileInfo *&file)
{static int int_size = sizeof(int);static int charpoint_size = sizeof(char*);if(_wrnode->w_offset + size + charpoint_size + int_size>= _wrnode->memsize){if(!_wrnode->memory){_wrnode->memory = new char[MEMSIZE];if(!_wrnode->memory){return 0;}_wrnode->memsize = MEMSIZE;	}else{__BlockNode * node = new __BlockNode();if(!node){			return 0;}	node->memory = new char[MEMSIZE];if(!node->memory){delete node;return 1;}			_blockSize++;_wrnode->next = node;_wrnode = node;	_wrnode->memsize = MEMSIZE;}}}memcpy((void*)(_wrnode->memory+_wrnode->w_offset),(void*)&file,charpoint_size);memcpy((void*)(_wrnode->memory+_wrnode->w_offset+charpoint_size),(void*)&size,int_size);memcpy((void*)(_wrnode->memory+_wrnode->w_offset+(charpoint_size+int_size)),(void*)log,size);_wrnode->w_offset += (size+int_size+charpoint_size);return 0;
}bool LogBlockManer::readLog(char * & log,int & size,__FileInfo *&file)
{static int int_size2 = sizeof(int);static int charpoint_size = sizeof(char*);if(_rdnode->r_offset >= _rdnode->w_offset){if(_rdnode != _wrnode){__BlockNode * node = _rdnode;_rdnode = _rdnode->next;delete [] node->memory;delete node;if(_rdnode->r_offset >= _rdnode->w_offset){return false;}}else{return false;}}memcpy((void*)&file,(void*)(_rdnode->memory + _rdnode->r_offset),charpoint_size);memcpy((void*)&size,(void*)(_rdnode->memory + _rdnode->r_offset + charpoint_size),int_size2);log = _rdnode->memory + (charpoint_size + int_size2+_rdnode->r_offset);_rdnode->r_offset += (size+charpoint_size+int_size2);return true;
}int LogBlockManer::Init()
{_wrnode = new __BlockNode();if(!_wrnode){return -1;}_head   = _wrnode;_rdnode = _wrnode;return 0;
}int LogBlockManer::setThreadmemsize(int size)
{_threadmem = size;return 0;
}

这篇关于浅析avro序列化和反序列化源码及提供两种数据序列存储思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/516279

相关文章

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

浅析Java中如何优雅地处理null值

《浅析Java中如何优雅地处理null值》这篇文章主要为大家详细介绍了如何结合Lambda表达式和Optional,让Java更优雅地处理null值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录场景 1:不为 null 则执行场景 2:不为 null 则返回,为 null 则返回特定值或抛出异常场景

SpringValidation数据校验之约束注解与分组校验方式

《SpringValidation数据校验之约束注解与分组校验方式》本文将深入探讨SpringValidation的核心功能,帮助开发者掌握约束注解的使用技巧和分组校验的高级应用,从而构建更加健壮和可... 目录引言一、Spring Validation基础架构1.1 jsR-380标准与Spring整合1

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

SpringBatch数据写入实现

《SpringBatch数据写入实现》SpringBatch通过ItemWriter接口及其丰富的实现,提供了强大的数据写入能力,本文主要介绍了SpringBatch数据写入实现,具有一定的参考价值,... 目录python引言一、ItemWriter核心概念二、数据库写入实现三、文件写入实现四、多目标写入

如何配置Spring Boot中的Jackson序列化

《如何配置SpringBoot中的Jackson序列化》在开发基于SpringBoot的应用程序时,Jackson是默认的JSON序列化和反序列化工具,本文将详细介绍如何在SpringBoot中配置... 目录配置Spring Boot中的Jackson序列化1. 为什么需要自定义Jackson配置?2.

使用Python将JSON,XML和YAML数据写入Excel文件

《使用Python将JSON,XML和YAML数据写入Excel文件》JSON、XML和YAML作为主流结构化数据格式,因其层次化表达能力和跨平台兼容性,已成为系统间数据交换的通用载体,本文将介绍如何... 目录如何使用python写入数据到Excel工作表用Python导入jsON数据到Excel工作表用

Mysql如何将数据按照年月分组的统计

《Mysql如何将数据按照年月分组的统计》:本文主要介绍Mysql如何将数据按照年月分组的统计方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql将数据按照年月分组的统计要的效果方案总结Mysql将数据按照年月分组的统计要的效果方案① 使用 DA

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt