Skip to content

{ Monthly Archives } 八月 2008

Tiny CC

转自 IBM developerWorks 中国  Tiny CC 本 文介绍 GNU/Linux 系统上最小的 C 语言编译器 Tiny C 编译器。Tiny C 编译器不仅仅是一个常规意义上的 C 语言编译器,它还使得用户可以像使用脚本语言一样使用 C 语言进行快捷的脚本编程。我们着重介绍用 C 语言进行脚本程序开发的魅力。这个系列将由三篇文章组成,这是第一篇,介绍;在第二篇中,我们将说明如何用标准 C 语言完成通常用 sed 和 awk 完成的字符串处理的工作;在第三篇中,我们将说明如何在自己的编译器项目中使用 TCC 作为机器代码生成器。 TCC 介绍 在 下文中,我们说 Tiny C 编译器、Tiny CC、或者 TCC 都是指的这个 Fabrice Bellard 发明的 GNU/Linux 环境下最小的 ANSI C 语言编译器。TCC 的主页在文后的参考资料中列出。在 Debian GNU/Linux 系统中,可以方便的用 apt-get install [...]

生活琐碎

当开幕式的火炬点燃的时候,我正在公司的角落里跟 iebook 搏斗着——本来闹运开幕这天是可以不必来公司,可以在家上班的,但为了挣一点零花钱,答应帮别人做一个电子书,于是就不辞辛苦的又赶到公司,从早上11点一直做到晚上10点。 原以为家里的本本太慢,公司的台式机应该会好一些,哪知道 iebook 程序做的那么烂,当页数超过 50 页的时候,就卡的不行了:时不时的报 “out of memory”(程序都没有处理一下报错信息,直接把 window 函数的返回信息给打印了出来),打开一个元素需要30秒,插入一副图片需要50秒,还有无法保存项目文件,这才是最致命的。 央视的开幕式,看起来烂的不行,一如每年的春晚。但后来看了 NBC 的版本才知道,原来开幕式本身,确实不错。开幕式是一个不错的造星机会,不管是唱歌的小女孩,还是领队的小男孩,“出世十年无人问,一夜闹运天下知”。 9号,去唐智星暂时住的地方,在委托方的要求下对“朗诵古诗文对高中生心理的影响” 电子书作最后的润色定稿。2G内存的机器,跑 iebook 还是那么慢,一边做电子杂志,一边看中国队在闹运上争金夺银。好不容易才算最终完成,外面已经是万家灯火了。 10号电子书交付通过,去拿钱,却刚好碰到北京的暴雨。大约因为开幕式的时候,所谓的人工干预降雨,虽然保证了当时没有下雨,不为人知的副作用却还是有的——河北暴雨,北京暴雨,接连几天,四处天象大乱。手握未知的力量,虽然强大,却不受控制,一旦释放,看得见的利与看不见的害,如何权衡取舍? 周一上班,与源源,志勇一同搬下到了17层。搬来搬去,按源源的话说,是已经麻木了。这回搬到的位置却还不错,正朝西:中国化工楼顶的草坪似乎就在眼前,小树,假山,静默的凉亭;稍远是更高的第三极;越过第三极的玻璃墙面,远远的西山绵延起伏。 搬到这边,工作环境从 CentOS 换到 FreeBSD ,Bash 也换成了 Csh 。继续用 CSF (Common Server Framework),搭建 Sina S3 (Simple Storage Service)的 Dispatcher 。

大量小文件的实时同步方案

 传统的文件同步方案有rsync(单向) 和 unison(双向)等,它们需要扫描所有文件后进行比对,差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将非常耗时。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。 之前看了Amazon的Dynamo的设计文档, 它们每个节点的数据是通过Hash Tree来实现同步,既有通过日志来同步的软实时特点(msyql, bdb等),也可以保证最终数据的一致性(rsync, unison等)。Hash Tree的大体思路是将所有数据存储成树状结构,每个节点的Hash是其所有子节点的Hash的Hash,叶子节点的Hash是其内容的Hash。这样一 旦某个节点发生变化,其Hash的变化会迅速传播到根节点。需要同步的系统只需要不断查询跟节点的hash,一旦有变化,顺着树状结构就能够在logN级 别的时间找到发生变化的内容,马上同步。 文件系统天然的是树状结构,尽管不是平衡的数。如果文件的修改时间是可靠的,可以表征文件的变化,那就可以用它作为文件的Hash值。另一方面,文 件的修改通常是按顺序执行的,后修改的文件比早修改的文件具有更大的修改时间,这样就可以把一个目录内的最大修改时间作为它的修改时间,以实现Hash Tree。这样,一旦某个文件被修改,修改时间的信息就会迅速传播到根目录。 一般的文件系统都不是这样做的,目录的修改时间表示的是目录结构最后发生变化的时间,不包括子目录,否则会不堪重负。因为我们需要自己实现这个功 能,利用Linux 2.6内核的新特性inotify获得某个目录内文件发生变化的信息,并把其修改时间传播到它的上级目录(以及再上级目录)。Python 有 pyinotify,watch.py的代码如下: #!/usr/bin/python      from pyinotify import *   import os, os.path      flags = IN_CLOSE_WRITE|IN_CREATE|IN_Q_OVERFLOW   dirs = {}   base = ’/log/lighttpd/cache/images/icon/u241′   base = ’tmp’      class UpdateParentDir(ProcessEvent):       def process_IN_CLOSE_WRITE(self, event):           print ’modify’, event.pathname           mtime = os.path.getmtime(event.pathname)           p = event.path           while p.startswith(base):               m = os.path.getmtime(p)               if m < mtime:                   print ’update‘, p                   os.utime(p, (mtime,mtime))               elif m > mtime:                   mtime = m               p = os.path.dirname(p)              process_IN_MODIFY = process_IN_CLOSE_WRITE          def process_IN_Q_OVERFLOW(self, event):           print ’over flow’           max_queued_events.value *= 2          def process_default(self, event):           pass      wm = WatchManager()   notifier = Notifier(wm, UpdateParentDir())   dirs.update(wm.add_watch(base, flags, rec=True, auto_add=True))   [...]