index = Redwood::Index.new
index.load
-(1 ... index.index.reader.max_doc).each do |i|
- next if index.index.deleted? i
- d = index.index[i]
- puts [d[:message_id], "(" + d[:label] + ")"] * " "
+index.each_message do |m|
+ puts "#{m.id} (#{m.labels * ' '})"
end
## delete any messages in the index that claim they're from one of
## these sources, but that we didn't see.
- ##
- ## kinda crappy code here, because we delve directly into the Ferret
- ## API.
- ##
- ## TODO: move this to Index, i suppose.
- if (target == :all || target == :changed) && !opts[:start_at]
+ if (target == :all || target == :changed)
$stderr.puts "Deleting missing messages from the index..."
num_del, num_scanned = 0, 0
sources.each do |source|
raise "no source id for #{source}" unless source.id
- q = "+source_id:#{source.id}"
- q += " +source_info: >= #{opts[:start_at]}" if opts[:start_at]
- index.index.search_each(q, :limit => :all) do |docid, score|
+ index.each_message :source_id => source.id do |m|
num_scanned += 1
- mid = index.index[docid][:message_id]
- unless seen[mid]
- puts "Deleting #{mid}" if opts[:verbose]
- index.index.delete docid unless opts[:dry_run]
+ unless seen[m.id]
+ next unless m.source_info >= opts[:start_at] if opts[:start_at]
+ puts "Deleting #{m.id}" if opts[:verbose]
+ index.drop_entry m.id unless opts[:dry_run]
num_del += 1
end
end
if opts[:optimize]
$stderr.puts "Optimizing index..."
- optt = time { index.index.optimize unless opts[:dry_run] }
+ optt = time { index.optimize unless opts[:dry_run] }
$stderr.puts "Optimized index of size #{index.size} in #{optt}s."
end
rescue Redwood::FatalSourceError => e
include Singleton
- ## these two accessors should ONLY be used by single-threaded programs.
- ## otherwise you will have a naughty ferret on your hands.
- attr_reader :index
- alias ferret index
-
def initialize dir=BASE_DIR
@index_mutex = Monitor.new
if File.exists? dir
Redwood::log "loading index..."
@index_mutex.synchronize do
- @index = Ferret::Index::Index.new(:path => dir, :analyzer => @analyzer)
+ @index = Ferret::Index::Index.new(:path => dir, :analyzer => @analyzer, :id_field => 'message_id')
Redwood::log "loaded index of #{@index.size} messages"
end
else
field_infos.add_field :refs
field_infos.add_field :snippet, :index => :no, :term_vector => :no
field_infos.create_index dir
- @index = Ferret::Index::Index.new(:path => dir, :analyzer => @analyzer)
+ @index = Ferret::Index::Index.new(:path => dir, :analyzer => @analyzer, :id_field => 'message_id')
end
end
end
results.hits.map { |hit| hit.doc }
end
+ def each_docid opts={}
+ query = build_query opts
+ results = @index_mutex.synchronize { @index.search query, :limit => (opts[:limit] || :all) }
+ results.hits.map { |hit| yield hit.doc }
+ end
+
+ def each_message opts={}
+ each_docid opts do |docid|
+ yield build_message(docid)
+ end
+ end
+
+ def optimize
+ @index_mutex.synchronize { @index.optimize }
+ end
+
protected
class ParseError < StandardError; end
query.add_query Ferret::Search::TermQuery.new("label", "spam"), :must_not unless opts[:load_spam] || labels.include?(:spam)
query.add_query Ferret::Search::TermQuery.new("label", "deleted"), :must_not unless opts[:load_deleted] || labels.include?(:deleted)
query.add_query Ferret::Search::TermQuery.new("label", "killed"), :must_not if opts[:skip_killed]
+
+ query.add_query Ferret::Search::TermQuery.new("source_id", opts[:source_id]), :must if opts[:source_id]
query
end