NR-grep是由智利大学的Gonzalo Navarro开发的一款“快速、灵活的模式串匹配工具”,其优点在于Nrgrep几乎全部基于BNDM算法及其扩展,性能随着搜索问题复杂度的增加而平滑下降(Agrep剧烈下降)。而且支持精确搜索和允许错误的近似搜索(grep不支持近似搜索);而且Nrgrep将性能平滑性看做是模式复杂度的一个函数,一旦预测到BNDM算法搜索的代价太大,他将更换为Shift-And算法。
但是Nrgrep的一个缺点在于不支持多串匹配,我们的实验便是想在Nrgrep的基础上,设计出利用GPU性能提高的多字符串匹配程序。
/* nrgrep程序共有33个文件 */
首先让我们来分析一下Nrgrep程序的大体执行流程。
一、/* get the options */ and /* some consistency checks */
Nrgrep程序从Shell.c的main (int argc, char **argv)开始,第一步便是获取用户输入的后缀(如-i等后缀参数),这里调用了Linux中的特有头文件getopt.h中的getopt函数(ps:getopt.h为开发Linux带参数程序提供特有的方便),然后根据不同的后缀做出不同的switch-case处理(各后缀作用将在以后分析)。
二、/* get the pattern */
然后,开始对搜索字符串作分析(分析第一个字是否’^’,最后一个字是否’$’)和调用预处理函数searchPreproc (patt)——在search.c内定义,其参数patt传递了一个pattern。该函数的作用为“Preprocesses pat and creates a searchData structure for searching”,为搜索结构确定、初始化了搜索类型(如:SIMPLE,EXTENDED,REGULAR),不同类型指向了不同的处理函数:
=== simplePreproc(pat,tree,pos); esimplePreproc(pat,tree,pos,OptErrors); ===
=== extendedPreproc(pat,tree,pos); eextendedPreproc(pat,tree,pos,OptErrors); ===
=== regularPreproc(pat,tree,pos); eregularPreproc(pat,tree,pos,OptErrors); ===
接着再调用了recPreproc ()函数,该函数定义于record.c:“makes the preprocessing for record handling”。
三、/* search the files */
初始化工作做好后,便可以开始文件搜索(同时支持标准输入stdin,调用fileno(stdin))。
主要调用的函数有:
bufSetFile (B,f)
if (OptRecNumber || !OptRecPositive)
newm = recSearchRecFile (*files,B,sData);
/* searches the file handled by B for P using R as record
separator, but scans record by record. this is our way to
handle OptRecNumber or !OptRecPositive */
else newm = recSearchFile (*files,B,sData);
/* searches the file handled by B for P using R as record
separator, reports matches as appropriate and returns number
of matches */
其中函数搜索调用的是searchScan (byte **beg, byte **end, searchData *P)
/* Searches from *beg to *end-1 for P. Returns if it could find
it. In case of returning true, *beg and *end are set to limit
the printable record containing the occurrence of P */
四、/* final report */
输出最终结果
五、/* clean up */
释放个数据结构的空间