My linux Ruby application is using Ferret 0.11.4.  I created my own class 
IndexSearcher to contain 
the Searcher of multiple directories.  If I do not have the searcher.close 
called, the end of 
runner/console or runner/server will pop out with system error:
*** glibc detected *** irb: double free or corruption (fasttop): 0x0a51d6c0 ***
======= Backtrace: =========
/lib/libc.so.6[0x638ac1]
/lib/libc.so.6(cfree+0x90)[0x63c0f0]
/usr/lib/ruby/gems/gems/ferret-0.11.4/lib/ferret_ext.so[0x247d75]
/usr/lib/ruby/gems/gems/ferret-0.11.4/lib/ferret_ext.so[0x219745]
/usr/lib/libruby.so.1.8(rb_gc_call_finalizer_at_exit+0xa7)[0xc3e237]
/usr/lib/libruby.so.1.8[0xc239e7]
/usr/lib/libruby.so.1.8(ruby_cleanup+0x100)[0xc2c280]
/usr/lib/libruby.so.1.8(ruby_stop+0x1d)[0xc2c3ad]
/usr/lib/libruby.so.1.8[0xc372c1]
irb[0x804868d]
/lib/libc.so.6(__libc_start_main+0xe0)[0x5e5390]
irb[0x8048581]

Here is the code of my class.  Any sign of what is wrong with the memory 
handling?

class IndexSearcher

        attr_accessor :searcher, :sub_searchers, :object_type

        # @param paths [Array of String] full local paths
        def initialize( object_type, paths )
                # Would've used this way since it's simpler and said by author 
to be faster; but invalid paths 
will break this entirely
                # self.searcher = 
Ferret::Search::Searcher.new(Ferret::Index::IndexReader.new(paths) )

                self.sub_searchers = []
                paths.each do |cur_path|
                        begin
                                sub_s = Ferret::Search::Searcher.new(cur_path )
                                self.sub_searchers << sub_s if sub_s
                        rescue Exception => index_e
                                puts "** IndexSearcher.new: #{index_e.message}"
                        end
                end


                if self.sub_searchers.size > 0
                        self.searcher = 
Ferret::Search::MultiSearcher.new(self.sub_searchers)
                else
                        self.searcher = (Ferret::I.new).searcher
                end

                self.object_type = object_type
        end

        # This doc/[] has a different to Index method: argument only wants 
doc_id [Integer]
        def doc(doc_id)
                return self.searcher[doc_id]
        rescue Exception => e
                puts "** IndexSearcher(#{object_type}).doc #{doc_id}\n" << 
e.backtrace.join("\n")
                return nil
        end

        alias :[] :doc

        #############################
        # Querying methods

        def process_query(query)
                query.is_a?(Ferret::Search::Query) ? query : 
SearchIndex::QUERY_PARSER.parse(query)
        end

        def search(query, options = {})
                query_obj = process_query(query)
                self.searcher.search( query_obj, options )
        end

        def search_each (query, options = {})
                query_obj = process_query(query)
                self.searcher.search_each( query_obj, options )
        end

        def explain (query, doc)
                query_obj = process_query(query)
                self.searcher.explain( query_obj, doc )
        end

        # Segmentation Fault when index_searcher.highlight
        def highlight (query, doc_id, options = {})
                query_obj = process_query(query)
                doc = self.searcher[doc_id]
                field_value = doc[options[:field] ]

                field_index = Ferret::I.new(:analyzer => 
SearchIndex::STEMMING_ANALYZER)
                field_index << {:keywords => field_value}

                fvh = field_index.highlight(query, 0, options.merge({ :field => 
:keywords }) )
                return fvh
        rescue Exception => e
                puts "** IndexSearch.highlight('#{query}'): #{e.message}" # << 
e.backtrace.join("\n")
                return field_value
        end

        def doc_freq(field, term)
                self.searcher.doc_freq(field, term)
        end

        #############################
        # Self Util methods

        def reader
                self.searcher.reader
        end

        def size
                if reader
                        total_size = reader.num_docs
                else
                        total_size = 0
                        self.sub_searchers.each do |sub_searcher|
                                total_size += sub_searcher.reader.num_docs if 
sub_searcher.reader
                        end
                        return total_size
                end
        end

        alias :num_docs :size

        def close
                self.searcher.close
        end

end
_______________________________________________
Ferret-talk mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ferret-talk

Reply via email to