
C++
文章平均质量分 90
Terark-CTO-雷鹏
Terark可检索压缩技术作者。致力于让数据更小,访问更快。
展开
-
正则语言的 并 交 差
正则语言的 并 交 差作者: rockeet 发表日期: 2014年09月08日 分类: 自动机 评论: 0 条 阅读次数: 7 次 [编辑]正则表达式,描述的是正则语言, 学过形式语言与自动机理论的人应该都知道,正则语言在并、交、差、补运算下都是封闭的;但是,根据 Wikipedia 的描述,到目前为止,还没有任何一个已知的正则语法(Flavor)将交和差纳入正则语法。理转载 2014-09-08 17:31:07 · 5405 阅读 · 0 评论 -
DFA的实现
DFA的实现在工业界,DFA的有效实现一直是一个问题,龙书中提到了一种使用四个数组的通用DFA实现,在汉字分词算法中经常用到double array作为Trie的一种实现。四数组的是通用DFA的实现,双数组的仅能用于实现Trie。并且它们的创建速度慢,难以理解,内存占用也比较多,状态id的值域范围稀疏。我的实现我实现了一种很紧凑的DFA,这在某种程度上源于popcount带来的灵感。当原创 2012-09-05 18:25:51 · 8611 阅读 · 2 评论 -
千万注意,不要 hack std::string
前段时间被一个bug折磨了两个星期,最后发现竟然是如此一个陷阱——我为了减少内存用量并且减少一次内存拷贝,直接通过string.data()修改了string的内部表示。这与其说是一个陷阱,不如说是我自己给自己造了一个陷阱然后把自己给掉进去了。发病机制可以用如下代码简单的勾画出来:using namespace std; int main(int ar...2007-02-25 14:49:00 · 180 阅读 · 0 评论 -
使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用
// 使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用。#include <stdio.h>#include <string.h>/* 病毒或许可以使用这种技术有效地实现,不过这是我在写 Windows PE 文件 加壳程序的时候总结2005-12-02 23:01:00 · 105 阅读 · 0 评论 -
WinApi 参数的层次
我以前一直对WinApi参数太多,使用困难颇有微词,但是仔细想想,直接使用Api编程的情况是非常少的。Api难用点,功能强点,好过好用但功能弱。同时,仔细分析下Api的参数,能发现,它其实是很有设计原则的,我只归纳出以下:尽量使用单层参数,也是说,参数是简单数据类型,没有内嵌结构;尽量避免使用多层参数,也就是说,不得不使用结构传递参数的时候,结构里面尽量避免再内嵌其它结构。因此可以看到,一个...2008-06-03 17:36:00 · 257 阅读 · 0 评论 -
C 语言实现的 stl-like 算法
使用类似BOOST.PP技巧,自动生成代码,效率上小胜stl,主要抽象出一般的(sort/heap/search)算法中的compare,按成员类型、偏移、类尺寸分派至不同函数;性能比stl相应算法还略高,用法更简单:#include <febird/c/algorithm.h>using namespace std;struct A { int x, y; }; ...2009-04-08 10:46:38 · 288 阅读 · 0 评论 -
可变长度数据结构
固定长度的数据结构很简单,大家每天都在用。可变长度数据结构,都可以通过内嵌对象的形式,转化成固定长度的数据结构,大家每天也都在用,例如:struct person{ int id; string name; string address;};每个 person 对象的长度是固定的,但是,其内嵌的 name 和 address 是变长的。从...2009-09-27 17:12:00 · 150 阅读 · 0 评论 -
malloc/free 的开销,如何去掉这种开销?
一般的malloc实现,对一块已分配的内存,都有两个机器字的簿记,甚至更多。如果不需要排错,理论上讲,只需要一个字长的额外开销,用来记录这块内存的尺寸(放在intptr[-1]处是个好主意)。为什么需要这个开销呢?因为free传入的只是个指针,它不知道要释放多大的内存,因此free内部必须通过某种方式来获得这块内存的尺寸。可以想象,如果用 malloc/free 来作为一个关联数组(map...2009-10-18 15:58:00 · 129 阅读 · 0 评论 -
世界上应用最广泛的虚拟机是啥?
别说是JavaVM!正确答案:x86vmx86本身是一个硬件vm,它的指令系统是一个vm指令系统,通过翻译层后,才交给下面的risk内核。2009-10-18 16:19:00 · 167 阅读 · 0 评论 -
集成TerichDB的SSDB性能测试
目前很多互联网公司都在使用[SSDB](http://ssdb.io), 它是一款NoSQL的,高性能数据库,目标是替代Redis。我们在 TerichDB 原生 API 的基础上,实现了 LevelDB API,所有使用 LevelDB 的程序,不需要修改任何代码,只需要修改 Makefile,就可以使用 TerichDB,ssdb 就是这样的一个程序。为了方便大家编译、使用基于 TerichDB 的 ssdb原创 2016-06-22 13:09:39 · 3515 阅读 · 0 评论 -
理想的 huge page
现代计算机的内存越来越大,服务器动辄就有上百GB,甚至 TB 级别的内存,很多应用已经可以把全部数据都放入内存,这样,磁盘空间换取内存空间这个传统中虚拟内存最重要的需求已经相当弱化甚至不复存在。当然我们仍然需要虚拟内存的其它好处(进程隔离、内存保护等),但是,虚拟内存最大的缺点:地址转换开销,在很多应用中越来越突出。于是,大家想起了 huge page ,huge page 大幅减小了原创 2017-01-25 11:09:49 · 2139 阅读 · 0 评论 -
把自动机用作 Key-Value 存储
以前只有代码,最近简单写了一点文档: google code 上的链接(总是最新)自动机是什么DFA 的最小化将 DFA 用做字典无环DFA (ADFA, Acyclic DFA)编译内存用量/查询性能map 与 set自动机实用程序自动机的 C++接口DFA_InterfaceDAWG_Interface超级功能以拼音输入法为例原创 2013-08-15 11:51:38 · 9956 阅读 · 0 评论 -
cygwin 中 dll 路径
cygwin 中 dll 路径不是用 LD_LIBRARY_PATH 指定,而是 PATH,坑爹!原创 2014-04-29 00:37:01 · 3454 阅读 · 0 评论 -
rdtsc 备忘
from: http://stackoverflow.com/questions/6814792/why-is-clock-gettime-so-erraticstatic uint64_t rdtsc() {#if defined(__GNUC__)# if defined(__i386__) uint64_t x; __asm__ volatile ("转载 2014-01-09 17:12:59 · 3822 阅读 · 0 评论 -
多正则表达式匹配 (Multiple Regular Expression Matching) 中的动态 DFA 算法
前一段时间,在用 多正则表达式匹配工具 用于数十万任意的正则表达式时,以前一直担心的问题终于出现了:NFA 转化 DFA 时的指数爆炸,那样的 DFA 根本创建不出来,因为那些正则表达式之间有不可预料的各种交集!这个问题对我打击很大,我甚至顿时觉得 多正则表达式匹配工具 完全是个废柴,最多,是个玩具!但是,只有挑战,才能激励人的斗志,挖掘人的潜能。我想起了曾经对之不屑一顾的动态 DFA 匹配算原创 2014-01-05 21:43:43 · 6157 阅读 · 5 评论 -
多正则表达式匹配工具 的用法
2014年3月25日22:55从 http://code.google.com/p/febird/wiki/MultiRegexMatch 更新至最新版Introduction介绍Compileregex_builder 使用方法命令行选项与参数关于 -d 选项输入文件Regex.txt 的格式一个示例的Regex.txt非常重要!注意事项!匹配接口: 二进制模式原创 2013-12-17 17:34:56 · 9972 阅读 · 27 评论 -
有多个初始状态的 DFA
最近做了一项工作:允许一个 DFA 有多个起始状态(可以称作根: root)。这样有以下几个好处:对于多正则表达式匹配(Multiple Regular Expression Matching)的 DFA在创建多正则表达式匹配的 DFA 的过程中,有一个 DFA 的 Union 操作,这操作通过 NFA 到 DFA 的转化来完成,在这个过程中,如果状态膨胀失去控制(最坏情况是指数级,一般情原创 2013-11-28 22:17:55 · 7157 阅读 · 0 评论 -
gcc 4.7.3 的一个 c++11 bug
昨天一个朋友 checkout 了我的 febird 代码,编译时出现了一个诡异的错误。经过仔细勘察,他的 g++ 版本是 4.7.3,而我测试过的 g++4.7.2,g++4.8.2均无问题。后来修改代码,解决了那个问题,但要还原那个bug时,很费了一番力气。以下是还原的那个 bug 的一段简单代码,不过可能不是最简单的。#include struct A { int原创 2013-11-13 10:30:50 · 3696 阅读 · 1 评论 -
多正则表达式匹配(Multiple Regular Expression Matching)
目前 febird 中的自动机库已支持正则表达式,并且,支持的是多正则表达式匹配:给定 M 个正则表达式,每个正则表达式有一个 [0, M) 的唯一 ID,该算法为这些正则表达式生成一个 DFA。再给定一个输入文本 Text ,如果只计最长匹配,该 Text 可以匹配 M 个正则表达式中的的 K 个在该DFA上运行我的匹配算法,可以在 O(strlen(Text) + K) 的时间原创 2013-11-03 22:22:16 · 7703 阅读 · 15 评论 -
boost 这帮人也超级不靠谱
刚才开始用 boost::range,就查看了了一下 boost 源码,发现 boost-1.50 一个 bug,觉得应该在新版中已经修改了,下载了最新的 1.54 版,进去一看,bug 仍然在!接着,到 boost bug 追踪系统,准备提交这个 bug ,搜了一下,很快发现,这个bug 在 17 个月前,boost-1.49 就报告出来了: range::unique does not f原创 2013-09-24 10:58:36 · 2694 阅读 · 1 评论 -
一个很强大的Comparator生成器
项目地址:http://code.google.com/p/febird /** @brief 生成一个比较器(Comparator),兼键提取(KeyExtractor)类 使用这个宏生成的比较器可以作用在不同的对象上,只要这些对象有相同名称的成员, 并且可以作用在类型为成员类型的对象上。 - 假设: - 有 n 个类 class...2008-04-22 15:02:00 · 176 阅读 · 0 评论 -
通用的 LoserTree
项目地址:http://code.google.com/p/febird - 共有 n 个内部结点,n 个外部结点 - winner 只用于初始化时计算败者树,算完后即丢弃 - winner/loser 的第 0 个单元都不是内部结点,不属于树中的一员 - winner 的第 0 个单元未用 - m_tree 的第 0 个单元用于保存最终的赢者, 其它单元保存败者 - 该初始化需要的...2008-04-22 15:14:00 · 342 阅读 · 0 评论 -
字符串基数排序
对字符串使用基数排序,以前,我一直觉得:因为字符串的长度不一,无法使用基数排序。前两天因为有需要,忽然想通了!即便长短不一,也可以使用链式基数排序! 首先,将字符串长度当作最低有效位,因为基数排序是从最低有效位开始排的,就先用分配-收集算法对长度做一趟。对字符串中的具体某一位字符进行排序相比,算法是一样的,只是写法稍有不同。要将排序结果的lenRadix指针保存起来,后面要用。 接...2009-12-09 22:00:39 · 731 阅读 · 0 评论 -
memory FILE in C
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key....2009-06-30 17:18:00 · 146 阅读 · 0 评论 -
很基本也很诡异的fread, feof
先看一段非常简单的程序: #include <stdio.h> int main(int argc, char** argv) { char buf[8193]; FILE* fp = fopen("tmp.bin", "wb+"); fwrite(buf, 1, 8192, fp); fseek(fp, ...2009-07-03 18:12:00 · 466 阅读 · 0 评论 -
理想的 lazy load
在linux中碰到一个问题,可以描述如下编译 liba.so 动态库时,引用了 b.so 中的函数 bar(), 一个程序 d 引用了liba.so,如果在 d 的 makefile 中的 ld 不指定 -lb,将提示错误:liba.so undefined reference to `bar'我试过使用 -z lazy 选项,没有效果。我想原因大概是...原创 2010-01-12 20:21:11 · 149 阅读 · 0 评论 -
使用 std::map 查找 IP 范围
给定这样一个问题:有一组从IP范围到地理位置信息的数据,不同地点的IP范围没有重叠,实现从单个IP地址查到相应的地理位置。数据示例view plaincopy to clipboardprint?start end geo-loc 1000 2000 北京 3000 3500 上海 4000 ...2010-08-05 17:40:13 · 345 阅读 · 0 评论 -
对数复杂度的聚集算法
SQL 有5个标准聚集函数:SUM, AVG, MIN, MAX, COUNT, 一般情况下,这几个函数的时间复杂度至少都是O(n), n是结果集的尺寸。然而,给定表:CREATE TABLE ACCESS_LOG(accTime DATETIME, stayTime INTEGER, INDEX(accTime));如果要进行以下查询:SELECT AVG(stayTime) W...2010-08-05 18:24:20 · 136 阅读 · 0 评论 -
简单的代码生成器创建领域语言
有一类问题,代码模板相同,但有少部分地方不同,一般可以写一个复杂的程序,使用不同的选项,完成不同的任务。或者,把公共的部分抽象成一个代码库,然后在不同程序中引用。但是,如果公共的部分很少,并且比较“专用”,或者因为其它原因,比较难以部署。怎么办?实际上,有另一种完全不同的编程模式来实现:代码生成器。unix世界中最知名的代码生成器莫过于lex和yacc了。但是,不比每个代码生成器都那么复杂,比...原创 2010-02-01 14:30:46 · 134 阅读 · 0 评论 -
my PipelineProcessor
刚看到,intel tbb::pipeline 实现的功能,和我以前实现的一个pipeline : febird::thread::PipelineProcessor ,介绍:1. 多线程的 pipeline 设计模式2. 多线程 Pipeline 的改进 几乎就是同一个东西:多线程流水线执行,按次序,stage划分……可惜啊,它只在我的几个程序中用过,现在有了...原创 2010-02-01 15:43:21 · 180 阅读 · 0 评论 -
process-->thread-->coroutine
在现实世界中,基本是是按着这样的顺序演化:process-->thread-->coroutine/fiber其实是一个context切换开销从大到小的演化,process切换开销最大,需要切换地址空间,所有的CPU状态,所有其他资源thread切换只需要切换CPU状态,当然是大部分的CPU状态,而coroutine切换,只需要切换很少的CPU状态,而且全部都在用户地址空间运行,不...2008-12-11 23:50:00 · 152 阅读 · 0 评论 -
about boost::shared_ptr
boost::shared_ptr 对象中,有两个成员一个是对象 ptr,一个是引用计数类的指针,由于某种原因,我希望把 shared_ptr 放入一个指针大小的地方,却无法实现,只能用 intrusive_ptr,但是牵涉到的类又太多,改起来不现实,仔细想一下,其实 shared_ptr 完全可以只有一个指针大小,只要把对象指针放到引用计数类中就可以了,为什么shared_ptr作者不这么干?是...2008-12-11 12:59:00 · 251 阅读 · 0 评论 -
原来Fiber就是Coroutine
前段时间自作聪明的还以为自己发现了一个完美的解决异步IO的方法,还真太把自己当回事了。人家已经早有这个办法了,还有个学名,叫做Coroutine,在异步IO中的应用也已经非常多了,我真是太孤陋寡闻了。...2008-12-10 23:43:00 · 608 阅读 · 0 评论 -
C++ 的缺点
C++ 现在最时髦的用法是 template meta programming。booster 们对此非常津津乐道,我本人也是个狂热的booster。到了什么程度?不使用template 就浑身不舒服,不boost一下就感觉对不起C++。但是这种狂热带来的严重后果就是程序编译速度极慢无比,生成的执行程序尺寸超常。曾经一个 C++ 服务器程序,代码也就10000行左右,编译出来的执行程序竟然20M...2008-04-22 16:12:00 · 641 阅读 · 1 评论 -
多线程的 pipeline 设计模式
一个简单例子:有很多个html网页,网页的id、title、url、path等信息存在一个数据库表中,网页内容存储在一个磁盘阵列上。现在要把所有网页都读出来,统计其中的html标签、正文等信息,并写入另一个数据库表,怎样的设计最好呢?一般的想法是使用多个平行的线程,每个线程处理某个ID范围的网页。但是仔细分析就可以发现,对每个网页的处理可以分为以下处理步骤: ...2008-04-22 16:49:00 · 398 阅读 · 0 评论 -
多线程 Pipeline 的改进
项目地址:http://code.google.com/p/febird 如果一个任务的执行分多个步骤,有些步骤慢,有些步骤快,如果在处理时间长的步骤上使用更多线程,那么因为队列的缓冲作用,在平均处理时间上,这些步骤就可以大致持平了,从而导致更大的吞吐量。以前的 Pipeline 完全胜任这样的需求,但是,如果有一个这样的需求,考虑如下例子:有若干篇文章(百万以上),需要...2008-10-30 16:55:00 · 195 阅读 · 0 评论 -
泛型就意味着代码膨胀?
我所了解的泛型实现,也就C++和Java,C++靠的是用代码膨胀来满足性能,Java泛型则只是一个Sugar。现在使用C++泛型的人越来越多,生成的程序体积也越来越大。一个对10种数据和10种算子使用了泛型算法的程序,代码膨胀的最大可以达到100倍。但实际上,生成的代码“很模板”。现在的C++还没有C++0x 的 closure/auto 等功能,代码膨胀已经达到了很恐怖的程度。——比如使用了 ...2008-05-09 17:06:00 · 237 阅读 · 0 评论 -
memory pool 的高效实现
memory poolmalloc可以分配任意大小的内存,因此,在malloc内部,保存了一些簿记信息(至少有一个包含内存块尺寸的信息)。调用free时,可以正确释放。为了减少这些簿记开销,可以使用memory pool。根据使用情境,可以分为两种:1. 只分配固定大小的内存块,速度最快(normal path约10条机器指令)。2. 可分配不同大小的内存块,速度稍慢,但比ma...2009-10-23 02:40:00 · 216 阅读 · 0 评论 -
memory pool 的高效实现(代码)
mpool.h#ifndef __febird_c_mpool_h__#define __febird_c_mpool_h__#include "config.h"#ifdef __cplusplusextern "C" {#endif//------------------------------------------------------------...2009-10-23 03:01:00 · 271 阅读 · 0 评论 -
内嵌变长数据结构范例——trbstrmap<mapped>
以前的这篇文章介绍了嵌入的变长数据结构(embeded) 本文介绍一个使用这种思想实现的通用strmap容器,相当于:std::map<std::string, Mapped>。 实现上使用了我以前写的线索红黑树——相比标准map的实现,节省了一半的结点存储开销,而平均查找时间只付出很小的额外开销,并且没有代码膨胀问题。 使用大多数情况下tr...2009-11-03 17:43:06 · 193 阅读 · 0 评论