惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
博客园_首页
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
N
News | PayPal Newsroom
S
Security Archives - TechRepublic
量子位
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Cisco Blogs
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
Scott Helme
Scott Helme
S
Securelist
Security Latest
Security Latest
爱范儿
爱范儿
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
L
LINUX DO - 最新话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
月光博客
月光博客
T
Tailwind CSS Blog
Cloudbric
Cloudbric
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
D
DataBreaches.Net
博客园 - 【当耐特】
有赞技术团队
有赞技术团队

博客园 - duguguiyu

『Android开发精要』推荐 深入Android【八】 —— Activity间数据传输 深入Android【七】 —— 资源文件 深入Android 【六】 —— 界面构造 深入Android 【五】 —— 任务和进程 深入Android 【四】 —— 组件调用 深入Android 【三】 —— 组件入门 深入Android 【二】 —— 架构和学习 深入Android 【一】 —— 序及开篇 Symbian手记【五】 —— Symbian的异步框架 Symbian手记【三】 —— Symbian的描述符 Symbian手记【二】 —— Symbian对象构造 Symbian手记【一】 —— Symbian命名法 分布式基础学习【二】 —— 分布式计算系统(Map/Reduce) 分布式基础学习【一】 —— 分布式文件系统 Chrome源码剖析 【五】 Chrome源码剖析 【四】 Chrome源码剖析【三】 Chrome源码剖析【二】
Symbian手记【四】 —— Symbian的容器
duguguiyu · 2009-06-13 · via 博客园 - duguguiyu

【四】 Symbian的容器

Symbian在设计之初,没有拥抱STL,这就要求,它需要重新制作一些轮子,容器便是其中的一个。

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等数据查找和处理的接口。具体实现和底层的存储相关联,具体细节没看过相关资料,只能无条件信任它的实现没有如此废柴。。。

RArray系列容器

RArray家族有两个成员,RArray和RPointerArray,从Symbian的命名风格很容易想到,前者存放普通栈对象,后者存放指针。RArray系列的实现,与CArray相比,清晰纯洁多了,它们其实就是基于X *或X **的C数组的封装,接近于STL的vector模式,只不过,和STL相比,它的模板行为还是有点伪而已。

所有的Symbian书上,都会说当你需要接近vector这样的数组的时候,用RArray而不要使用CArrayFixFlat。原因是有很多的,本质上,CArray是被Symbian大而全思想脱了后腿,它的继承结构很深,每一层都要做一些额外的Check工作,降低了效率,而RArray基本就是为这个量身打造的,没有太多额外的开销,在Int,UInt等基本数据类型上,还不辞辛劳的做了模板特化,进一步提高了效率。因此,术业有专攻,性能强与CArrayFixFlat,也不是什么稀奇事情了。

其他容器

在Symbian中,还有一些容器,比如CDesCArray系列的Array,它们和CArray系列容器本是同根生,只不过换了个皮脸,针对描述符提供了额外的一些接口,可以更好的进行字符串比较等操作。而Symbian中,我并没有发现一些非线性的容器,比如map,比如hash,比如tree。如果有,那么就是我土鳖了,如果没有,其实也是我土鳖了,因为我实在琢磨不透Symbian怎么做这么个决定的。

Thin Templates

强行插播一些广告,关于Symbian的模板。众所周知,C++模板有两个特别优秀的特征:

  • 高效。编译期决定类型,保证运行期的运行效率。
  • 安全。编译期决定类型,保证运行期的安全。

但为了达到这样的效果,也是付出了成本的,那就是类型的膨胀,与运行期技术相比,程序体积增加了不少。作为一个手机操作系统,Symbian在模板的使用上,加了个pattern,企图鱼和熊掌兼得。具体来说,就是不利用模板高效的优点,仅利用模板安全的特征,用运行期的技术,减少程序体积,这层模板的皮,它们称之为Thin Templates。

从实现上来看,标准的一个模板容器的实现,可能就是:

template <class T>
class Array<T>
{
public:
    T GetData(int index);

private:
    T * data;
};

这样的话,如果有十个不同类型使用CArray,那么就会编译出十个不同的类,使得体积膨胀。于是Symbian的Thin Templates模式这么来做:

template <class T>
class Array<T> : private BaseArray
{
public:
    T GetData(int index);
};

class CBaseArray
{
protected:
    void * data;
};

表面上,还是一个模板类,但实际上,存储上并没有按照类型,而是统一转成了void *。用private继承,派生基类的存储,而摒弃基类的接口,重新构造基于模板参数的接口。这样一来,安全性保证了,很多错误在编译期就可以暴露出来,而由于底层实现没有用模板,节约了一部分体积开销,这种实现,类似于早期的Java模板,只是牺牲了性能优势,对于底层来说也许真的利大于弊,但对于自己的应用来说,就不一定了。因此,如果是自己做模板,考量一下应用场景,不需要拘泥所谓的Tiny Templates。。。

============================

下面是真的插播广告*_*,Symbian上的,有道购物助手, 现在已经发布。第一版功能还不算很丰富,有一些bug还在处理中。欢迎有S60 v3版的童鞋下载使用,努力拍砖。。。