CArray系列容器
Symbian的设计者,非常喜欢复杂的继承结构和保罗万象的类,CArray系列的容器,就是在这种理念下的产物。CArray是顺序容器,相当于STL的vector + list,以及更多。
CArray系列容器,在继承的最底端,也就是可实例化使用的类,都采用CArrayXxxYxx的命名方式,即:CArray + 对象单元存储方式 + 对象段存储方式。所谓对象单元存储方式,就是表征容器中每一个单元数据,是如何存放的,在CArray中,主要有四种:
Flat,容器中的每个数据,都是等长同类的;
Var,容器中的每个数据长度,可以是不同的;
Pak,容器中的数据分成若干部分,每一部分都有一个leading-byte表示这一段的长度,形如描述符;
Ptr,容器存放CBase子类对象的指针数据。
每个容器,都有一个重要的参数,它是一个整数,称为Granularity,即,每一组元素的个数。组是CArray容器分配内存的单位,在Granularity范畴内,元素都按照上述四种模式进行存储,但是,Granularity总是一个有限的数,当容器中元素填满Granularity大小,就需要新增空间来存储。每次新增空间,都是Granularity个单元,每一组单元之间,有两种连接模式,一种是Fix,一种是Seg。
在Symbian OS Explained中有一幅经典图片,各种Array的存储模式,一目了然,盗窃过来,如上所示。从存储上来看,Flat方式就有如数组,一个挨一个存在一起,Ptr看上去和Var一致,指针一个挨一个存在一起,指向堆中对象,但从本质上来看,Ptr的实现与Flat的底层类似,而Var则是转为指针定制。Pak的存储有些怪异,每一坨元素有一个leading-byte的个数参数,让人不由怀疑,这玩意整个就是为描述符处心积虑准备的。
而段与段之间,Fix的犹如vector,每次扩大存储容量,都需要进行内存的重新分配,适合用在定长的场景,而不是变长。而Seg,类似于List,段之间链表方式连接,如果Granularity的一个Seg对象,就彻底沦为了链表,毫无疑问,如果你需要不是的增加存储容量,Seg方式Array应该是你的最爱。。。
在接口层面,CArray支持AppendL,InsertL,Delete等数据写入的接口,也支持At,operator [] 之类的数据读取接口,还支持Sort,Find,Compress等数据查找和处理的接口。具体实现和底层的存储相关联,具体细节没看过相关资料,只能无条件信任它的实现没有如此废柴。。。