- 主题:如何写一个函数能够序列化任意结构
最早,需要做一个3层客户服务器工具,要求安全高效的处理高并发事务。这个工具是别人开始做的。是一个通用平台,在之上可以架构各种应用。最基本的功能就是在网络传输各种不同的结构数据。那个时代JAVA刚刚出世,C++也刚刚冒头,还没有什么序列化反序列化的概念,只有一个想法,对任意不明结构数据打包拆包。数据是在不同平台互相传输,struct在各个平台,包括windows,unix,小型机,微机之间互相传送,它们的成员大小,大头小头和边界对齐规则都是不同的。
那时开始使用socket,程序也不复杂,也没有抵抗ddos什么的概念,我问到开发者,这个平台对应用的最大贡献是什么?答曰,任意struct的打包拆包程序。
当时的模板只有2个参数,类型,长度,offset都是现算的。
我研究了一下他的算法,改进一下,把offset加入模板,在第一次使用这个模板时需要进行一次计算,以后就直接使用offset,效率大为提高。
当时还没有json,xml啥的,就是类似csv的,用分隔符分割的字符串。
成功以后,考虑到sql语句的生成,模板里增加了成员名,格式,主要针对数据库的时间量,和bind标志,解决不完全表结构引用的问题,也就是不对所有列的访问。就是说,到这一步,就解决了对sql进行序列化和反序列化问题。
这时就有了一个好处,在大型系统开发时,数据结构是经常变化的,只需要调整模板,大部分程序不需要修改,从新编译即可。我们称为柔性编程。
大型数据结构,写模板,即繁琐又易错,所以,开发组有专人负责维护模板系统。
这时,提出一个要求,应用客户端需要下载一些固定信息,一些表,每个表要写一个程序。能不能只提供表名就可以下载任意表。于是研究了数据库的数据字典,读出并转换,就可以制成模板,从模板就可以生成struct。这就构成了通用模板库。从柔性编程提高到泛型编程的高度。
而且,模板可以存储也可以传输。在服务器里构建了动态模板库,某个客户端访问了一个表,就把这个表的模板存到本地模板库,以后再有要求这个表的,就不必从数据库生成了。当然这个模板库也是需要维护的,在运行中改变了数据结构,要进行相应的变更。
【 在 hyperLee 的大作中提到: 】
: 怎么做到的?学习一下?
:
: #发自zSMTH@么么哒
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
比他早。
是C泛型,不是C++泛型,但是C++可以用。
我的能做数据库。它的只能序列化反序列化JSON,xml什么的,做不了SQL。我这个相当于ORM,Object Relational Mapping。C没有Object,有struct,所以叫做SRM。
他们是编译期处理的,我是运行期处理的。
比如多个类似的表做相同的操作,写一个程序就行,代入哪个模板,就做哪个表。他们的不行,几个表就得写几个程序。
比如,6个类似表做去重,去掉重复记录,一个程序解决了。
理念不同,我们那时候讲究程序数据独立,一个程序,可以处理很多不同数据。也就是所谓泛型。
现在是OOP,数据和处理程序绑定在一起。有多少种数据就有多少种程序。
【 在 callmebbser 的大作中提到: 】
: 和Google Protocol Buffers(protobuf)有什么差别?
:
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
比序列化反序列化更宽泛,包括了数据库处理。
可以在运行时处理。
例如:
客户端发出请求下载一个表,提供表名和检索条件,服务器按表名找到表结构,生成模板,再根据模板生成结构体数组。根据模板生成SQL语句。打开游标,绑定变量,执行语句,结果集自动进入结构体数组。
把这个数组序列化发到客户端。客户端根据模板将数据发序列化到本地结构体数组。
全过程就使用一个模板。
向数据库上传数据的过程类似。
这套机制要求不向客户端暴露数据库,不允许客户端直连数据库,必须通过服务器访问数据库。服务器是对客户端进行安全认证并授权。
【 在 callmebbser 的大作中提到: 】
: 和Google Protocol Buffers(protobuf)有什么差别?
:
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
getColumn(i)是通过绑定变量实现的,在打开游标的时候就可以把每个列绑定到结构数组对应的字段。
这样在execute之后,结果集就已经在结构数组里啦。
模板在第一次被使用时就会计算offset,这个对齐问题考虑在内了。由于工具库是编译好放在运行库里的,.a或.so,使用时连接即可,成熟的,不需要临时调试。
使用时只需要#include 一些.h,-l一些库,很简单。
【 在 DoorWay 的大作中提到: 】
: 明白了,除了根据表定义生成数据结构,带正反序列化到某种指定结构化的文档或数据格式,
: 你的另一个研究点在于从数据库里拖出一块内存,像解析流一样,或先分行,再把每行分成字段(根据每个成员变量的描述,即字节长度),这样一大块内存(查询结果)就变成了多个C的结构体。
: 只考虑字节长度是不够的,还要考虑对齐问题。这用C语言来做描述挺合适。我的应用数据库不是重点,没考虑这个。不过好奇,每种数据库查询结果,内存块里各行的各字段,对齐是一样的吗?应该也需要实战调试到稳定吧。
: ...................
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
是。每种数据库都有查询表结构的语句,各不相同。所以每种数据库的底层不同。
但是应用层是相同的,缺点是在一个程序里不能同时操作不同的数据库。
遇到过临阵换数据库的事。开始签约时用的ORACLE,都开干几周了,业主突然提出改DB2,经过2天时间更换了底层,上层程序基本不用修改。
【 在 DoorWay 的大作中提到: 】
: 换了一种数据库,你这也方案也得改改生成那部分代码,生成新表的“模板”,对吧?
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
你用JAVA就行。问题是,许多系统不可能用JAVA重写。
却可以配上模板增强柔性。
我也确实弄过JAVA的,序列化还是需要提供一个列表,说明需要操作的成员。
反序列化json比较省事。但是反序列化csv,依然需要成员名列表。
【 在 tortelee 的大作中提到: 】
: 跟你们讲个成熟的方法,就是重新发明一种语言,简单的,然后需要序列化的,你都用这种语言。 再把这个语言转成c++. 解析的过程你是可以控制的,在这个过程,获取类的信息等。
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
我做的也包括这个,写一个元数据转换器,把元数据转换成struct和template。
很简单。不需要新语言。
没有用struct生成template的原因是,template是基于数据库的,数据类型比struct丰富得多。
比如时间日期类型,可以对应char[],但是有不同格式,字节数不同。
还可以对应成整型,表示从时间原点到某时刻的天数,分钟数,秒数,微秒数。
所以,在template里还有格式的表述,这些在struct里是没有的。
因此,即使在JAVA里,还是给配了一些模板工具来处理这些问题。反射,只解决了数据类型和位置,解决不了格式问题。
原来还想做DECIMAL类型及其算法,比较依赖数据库,后来没有做。
【 在 tortelee 的大作中提到: 】
: 跟你们讲个成熟的方法,就是重新发明一种语言,简单的,然后需要序列化的,你都用这种语言。 再把这个语言转成c++. 解析的过程你是可以控制的,在这个过程,获取类的信息等。
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
弄过,还是需要列出成员名。
否则不知道弄哪个。还需要说明格式。
比如,一个整数,序列化成 YYYY-MM-DD的日期格式。
或者反之。
参见58楼模板和57楼数据。
【 在 hgoldfish 的大作中提到: 】
: 现在 Java 早就不用了。
: 直接传个 Object 给序列化库,就会用反射把需要序列化的字段给找出来。
: 好一点的序列化库找到需要序列化的字段以后还会为这个类型生成对应的序列化字节码,再加上 JIT,速度暴快。
: ...................
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
你这个跟我非常接近了,我也考虑过用tuple存储模板。
用c一个是因为时间早,最早在95年,服务器是c,小型机,客户端是C++,windows,必须考虑2用。
还有,使用struct比较容易计算offset,cpp的class,有时会塞给你构造函数和析构函数,offset计算不靠谱。
我所说的序列化反序列化泛指,to_Json,to_CSV,to_XML,TO_SQL,,,,
【 在 DoorWay 的大作中提到: 】
: 你有一篇博客在完整的描述这个方案吗?
: 我也做过一个类似的,读sqllite的表结构,每张表生成一个对应的结构体,带From/To函数。
: 当时的需求是xml。
: ...................
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
你这个太专业了,不是所有人都会用。
我说过是模板库,.a或.so,include .h,-l库即可,任何稍有基础的都会用,我带过若干课题组,培训半天基本都能掌握。
完整的方案,,,这个东西是一点点搞起来的,有使用手册。可以到QQ群,SDBC技术群,到文件区下载文档和源码,以及部分工具和例子,开源。
进群请说明技术目的。
【 在 DoorWay 的大作中提到: 】
: 你有一篇博客在完整的描述这个方案吗?
: 我也做过一个类似的,读sqllite的表结构,每张表生成一个对应的结构体,带From/To函数。
: 当时的需求是xml。
: ...................
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*