Class: Gonzui::Searcher

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/gonzui/searcher.rb

Instance Method Summary collapse

Methods included from Util

assert, assert_equal, assert_equal_all, assert_non_nil, assert_not_reached, benchmark, command_exist?, commify, eprintf, format_bytes, program_name, protect_from_signals, require_command, set_verbosity, shell_escape, unix?, vprintf, windows?, wprintf

Constructor Details

#initialize(dbm, search_query, at_most_nresults) ⇒ Searcher

Returns a new instance of Searcher.



75
76
77
78
79
80
81
82
# File 'lib/gonzui/searcher.rb', line 75

def initialize(dbm, search_query, at_most_nresults)
  @dbm = dbm
  @search_query = search_query
  @at_most_nresults = at_most_nresults
  # If "all" is specified, both IDs become nil. No problem.
  @target_format_id = @dbm.get_format_id(@search_query.format)
  @target_license_id = @dbm.get_license_id(@search_query.license)
end

Instance Method Details

#break_needed?(option) ⇒ Boolean

Returns:

  • (Boolean)


195
196
197
198
199
200
201
202
203
204
205
# File 'lib/gonzui/searcher.rb', line 195

def break_needed?(option)
  judge = false
  case option
  when :all, :find_one_extra
  when :exact
    judge = true
  else
    assert_not_reached
  end
  return judge
end

#filter_package_ids(package_ids) ⇒ Object



122
123
124
125
126
# File 'lib/gonzui/searcher.rb', line 122

def filter_package_ids(package_ids)
  package_ids = filter_package_ids_by_format(package_ids)
  package_ids = filter_package_ids_by_license(package_ids)
  return package_ids
end

#filter_package_ids_by_format(package_ids) ⇒ Object



112
113
114
115
# File 'lib/gonzui/searcher.rb', line 112

def filter_package_ids_by_format(package_ids)
  filter_package_ids_by_property(package_ids, @target_format_id, 
                                 :get_format_ids_from_package_id)
end

#filter_package_ids_by_license(package_ids) ⇒ Object



117
118
119
120
# File 'lib/gonzui/searcher.rb', line 117

def filter_package_ids_by_license(package_ids)
  filter_package_ids_by_property(package_ids, @target_license_id, 
                                 :get_license_ids_from_package_id)
end

#filter_package_ids_by_property(package_ids, target_id, get_ids) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/gonzui/searcher.rb', line 102

def filter_package_ids_by_property(package_ids, target_id, get_ids)
  if target_id
    package_ids = package_ids.find_all {|package_id|
      format_ids = @dbm.send(get_ids, package_id)
      format_ids.include?(target_id)
    }
  end
  return package_ids
end

#filter_path_ids(path_ids) ⇒ Object



148
149
150
151
152
# File 'lib/gonzui/searcher.rb', line 148

def filter_path_ids(path_ids)
  path_ids = filter_path_ids_by_format(path_ids)
  path_ids = filter_path_ids_by_license(path_ids)
  return path_ids
end

#filter_path_ids_by_format(path_ids) ⇒ Object



138
139
140
141
# File 'lib/gonzui/searcher.rb', line 138

def filter_path_ids_by_format(path_ids)
  filter_path_ids_by_property(path_ids, @target_format_id, 
                              :get_format_id_from_path_id)
end

#filter_path_ids_by_license(path_ids) ⇒ Object



143
144
145
146
# File 'lib/gonzui/searcher.rb', line 143

def filter_path_ids_by_license(path_ids)
  filter_path_ids_by_property(path_ids, @target_license_id, 
                              :get_license_id_from_path_id)
end

#filter_path_ids_by_property(path_ids, target_id, get_id) ⇒ Object



128
129
130
131
132
133
134
135
136
# File 'lib/gonzui/searcher.rb', line 128

def filter_path_ids_by_property(path_ids, target_id, get_id)
  if target_id
    path_ids = path_ids.find_all {|path_id|
      format_id = @dbm.send(get_id, path_id)
      format_id == target_id
    }
  end
  return path_ids
end

#find_ids(get_proc, filter_proc) ⇒ Object

Raises:



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/gonzui/searcher.rb', line 154

def find_ids(get_proc, filter_proc)
  ids = nil
  @search_query.words.each {|word|
    word_id = find_word_id(word)
    tmp = get_proc.call(word_id)
    tmp = filter_proc.call(tmp)
    ids = if ids.nil? then tmp else ids & tmp end
    break if ids.empty?
  }
  raise NotFoundError.new if ids.nil?
  return ids
end

#find_package_id(package_name) ⇒ Object

Raises:



90
91
92
93
94
# File 'lib/gonzui/searcher.rb', line 90

def find_package_id(package_name)
  package_id = @dbm.get_package_id(package_name)
  raise NotFoundError.new unless package_id
  return package_id
end

#find_package_id_from_path_id(path_id) ⇒ Object



96
97
98
99
100
# File 'lib/gonzui/searcher.rb', line 96

def find_package_id_from_path_id(path_id)
  package_id = @dbm.get_package_id_from_path_id(path_id)
  assert_non_nil(package_id)
  return package_id
end

#find_package_idsObject



167
168
169
170
171
# File 'lib/gonzui/searcher.rb', line 167

def find_package_ids
  get_proc = lambda {|word_id| @dbm.get_package_ids(word_id) }
  filter_proc = lambda {|ids| filter_package_ids(ids) }
  return find_ids(get_proc, filter_proc)
end

#find_path_id(path) ⇒ Object

Raises:



173
174
175
176
177
# File 'lib/gonzui/searcher.rb', line 173

def find_path_id(path)
  path_id = @dbm.get_path_id(path)
  raise NotFoundError.new unless path_id
  return path_id
end

#find_path_ids(package_id) ⇒ Object



179
180
181
182
183
184
185
# File 'lib/gonzui/searcher.rb', line 179

def find_path_ids(package_id)
  get_proc = lambda {|word_id| 
    @dbm.get_path_ids_from_package_and_word_id(package_id, word_id)
  }
  filter_proc = lambda {|ids| filter_path_ids(ids) }
  return find_ids(get_proc, filter_proc)
end

#find_word_id(word) ⇒ Object

Raises:



84
85
86
87
88
# File 'lib/gonzui/searcher.rb', line 84

def find_word_id(word)
  word_id = @dbm.get_word_id(word)
  raise NotFoundError.new unless word_id
  return word_id
end

#get_result_item(path_id, option) ⇒ Object

FIXME: It’s too complicated



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/gonzui/searcher.rb', line 208

def get_result_item(path_id, option)
  package_id = @dbm.get_package_id_from_path_id(path_id)
  item = ResultItem.new(package_id, path_id)
  @search_query.each {|qitem|
    nfound = 0
    if qitem.phrase?
      finder = PhraseFinder.new(@dbm, path_id, qitem.value)
      finder.each {|occ|
        if option == :find_one_extra and nfound >= 1
          item.has_more_in_path
          break
        end
        item.push(occ)
        nfound += 1
        break if break_needed?(option)
      }
    else
      word_id = find_word_id(qitem.value)
      @dbm.find_word_info(path_id, word_id) {|info|
        next unless match_target?(info, qitem.property)
        occ = Occurrence.new(info.byteno, info.lineno, qitem.value.length)
        if option == :find_one_extra and nfound >= 1
          item.has_more_in_path
          break
        end
        item.push(occ)
        nfound += 1
        break if break_needed?(option)
      }
    end
    return nil if nfound == 0
  }
  return item
end

#match_target?(info, property) ⇒ Boolean

Returns:

  • (Boolean)


187
188
189
190
191
192
193
# File 'lib/gonzui/searcher.rb', line 187

def match_target?(info, property)
  if property
    return info.match?(property)
  else
    return true
  end
end

#searchObject



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/gonzui/searcher.rb', line 310

def search
  retried = false
  begin
    result = if @search_query.path
               search_with_path
             elsif @search_query.package
               search_with_package
             else
               search_without_scope
             end
    return result
  rescue NotFoundError
    if retried == false and @search_query.tokenize_all
      retried = true
      retry
    end
    return SearchResult.new
  end
end

#search_with_packageObject



276
277
278
279
# File 'lib/gonzui/searcher.rb', line 276

def search_with_package
  package_id = find_package_id(@search_query.package)
  return search_with_package_internal(package_id)
end

#search_with_package_internal(package_id) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/gonzui/searcher.rb', line 257

def search_with_package_internal(package_id)
  result = SearchResult.new
  path_ids = find_path_ids(package_id)
  path_ids.each {|path_id|
    item = get_result_item(path_id, :find_one_extra)
    next if item.nil?
    result.push(item)
    if result.length >= @at_most_nresults
      result.limit_exceeded = true
      break
    end
  }
  if result.length == 1 and result.first.has_more?
    return search_with_path_internal(result.first.path_id)
  else
    return result
  end
end

#search_with_pathObject



252
253
254
255
# File 'lib/gonzui/searcher.rb', line 252

def search_with_path
  path_id = find_path_id(@search_query.path)
  return search_with_path_internal(path_id)
end

#search_with_path_internal(path_id) ⇒ Object

Raises:



243
244
245
246
247
248
249
250
# File 'lib/gonzui/searcher.rb', line 243

def search_with_path_internal(path_id)
  result = SearchResult.new
  item = get_result_item(path_id, :all)
  raise NotFoundError.new if item.nil?
  item.has_more_in_path if item.list.length > @search_query.length
  result.push(item)
  return result
end

#search_without_scopeObject



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/gonzui/searcher.rb', line 281

def search_without_scope
  result = SearchResult.new
  package_ids = find_package_ids
  package_ids.each {|package_id|
    list = []
    path_ids = find_path_ids(package_id)
    path_ids.each {|path_id|
      item = get_result_item(path_id, :find_one_extra)
      next if item.nil?
      list.push(item)
      break if list.length >= 2
    }
    next if list.empty?
    item = list.first
    item.has_more_in_package if list.length > 1
    result.push(item)
    if result.length >= @at_most_nresults
      result.limit_exceeded = true
      break
    end
  }
  if result.length == 1
    return search_with_package_internal(result.first.package_id)
  else
    return result
  end
end