红宝石人有雪貂.有人知道Python的任何类似举措吗?我们目前正在使用PyLucene,但我想调查转向纯Python搜索.
我正在通过Ferret(Lucene的Ruby端口)代码来解决一个bug.Ferret代码主要是Ruby的C扩展.我遇到了垃圾收集器的一些问题.我设法修复它,但我不完全理解我的修复=)我希望有更深入的Ruby和C扩展知识的人(这是我在Ruby的第3天)可以详细说明.谢谢.
情况如下:
在Ferret C代码的某些地方,我将返回一个"Token"到Ruby的土地.代码看起来像
static VALUE get_token (...)
{
...
RToken *token = ALLOC(RToken);
token->text = rb_str_new2("some text");
return Data_Wrap_Struct(..., &frt_token_mark, &frt_token_free, token);
}
Run Code Online (Sandbox Code Playgroud)
frt_token_mark调用rb_gc_mark(token-> text)和frt_token_free只用free(令牌)释放令牌
在Ruby中,此代码与以下内容相关:
token = @ input.next
基本上,@ input设置为某个对象,在其上调用下一个方法会触发get_token C调用,该调用返回一个令牌对象.
在Ruby领域,我做了类似w = token.text.scan('\ w +')的事情.
当我在一个1循环内运行此代码(以隔离我的问题)时,在某些时候(大约当我的ruby进程mem足迹达到256MB,可能是一些GC阈值)时,Ruby会因为错误而死
扫描方法调用终止对象
或者只是核心转储.我的猜测是token.text被垃圾收集了.
我不太了解Ruby C扩展,知道Data_Wrap_Struct返回对象会发生什么.在我看来,Ruby land,token =中的赋值应该创建对它的引用.
我的"解决方法"/"修复"是在@input引用的对象中创建一个Ruby实例变量,并将令牌文本存储在那里,以获得对它的额外引用.所以C代码看起来像
RToken *token = ALLOC(RToken);
token->text = rb_str_new2(tk->text);
/* added code: prevent garbage collection */
rb_ivar_set(input, id_curtoken, token->text);
return Data_Wrap_Struct(cToken, &frt_token_mark, &frt_token_free, token);
Run Code Online (Sandbox Code Playgroud)
所以现在我在输入实例变量中创建了一个"curtoken",并在那里保存了一个文本的副本...我已经注意在@input的类的免费回调中删除/删除这个引用.
使用此代码,它的工作原理是我不再获得终止对象错误.
修复似乎对我有意义 - 它为token.text字符串保留了额外的引用,因此在下次调用@input.next之前不会删除token.text的实例(此时a不同的token.text替换curtoken中的旧值.
我的问题是:为什么以前不起作用?不应该Data_Wrap_Structure返回一个对象,当在Ruby域中分配时,该对象具有有效的引用而不被Ruby删除?
谢谢.
我试图运行一个需要安装雪貂的OpenSource项目.在使用gem install ferret安装它时,它会给出这个错误 - >
构建原生扩展.这可能需要一段时间...错误:安装雪貂时出错:错误:无法构建gem原生扩展.
C:/Ruby/bin/ruby.exe extconf.rb创建Makefile
nmake'nmake'未被识别为内部或外部命令,可操作程序或批处理文件.
Gem文件将保留在C:/Ruby/lib/ruby/gems/1.8/gems/ferret-0.11.6中进行检查.结果记录到C:/Ruby/lib/ruby/gems/1.8/gems/ferret-0.11.6/ext/gem_make.out
所以,我尝试安装nmake(nmake15.exe),但我找不到它.它不能安装在Windows 7上.如何安装雪貂?