picky 4.14.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  # Information.
2
2
  #
3
- print "Compiling on Ruby 1.9"
3
+ puts
4
+ print "Compiling on Ruby #{RUBY_VERSION}"
4
5
  if defined?(RbConfig)
5
6
  RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
6
7
  print " with CC set to #{RbConfig::MAKEFILE_CONFIG['CC']}"
@@ -10,7 +11,6 @@ puts "."
10
11
  # Compile.
11
12
  #
12
13
  require 'mkmf'
13
-
14
14
  abort 'need ruby.h' unless have_header("ruby.h")
15
-
16
- create_makefile('performant')
15
+ create_makefile 'picky/picky'
16
+ puts
@@ -79,7 +79,7 @@ static inline VALUE memory_efficient_intersect(VALUE self, VALUE unsorted_array_
79
79
 
80
80
  VALUE p_mPerformant, p_cArray;
81
81
 
82
- void Init_performant() {
82
+ void Init_picky() {
83
83
  p_mPerformant = rb_define_module("Performant");
84
84
  p_cArray = rb_define_class_under(p_mPerformant, "Array", rb_cObject);
85
85
  rb_define_singleton_method(p_cArray, "memory_efficient_intersect", memory_efficient_intersect, 1);
@@ -212,13 +212,17 @@ module Picky
212
212
  @intermediate_result_id ||= "#{host}:#{pid}:picky:result"
213
213
  end
214
214
 
215
+ def identifiers_for combinations
216
+ combinations.inject([]) do |identifiers, combination|
217
+ identifiers << "#{PICKY_ENVIRONMENT}:#{combination.identifier}"
218
+ end
219
+ end
220
+
215
221
  # Uses Lua scripting on Redis 2.6.
216
222
  #
217
223
  module Scripting
218
224
  def ids combinations, amount, offset
219
- identifiers = combinations.inject([]) do |identifiers, combination|
220
- identifiers << "#{PICKY_ENVIRONMENT}:#{combination.identifier}"
221
- end
225
+ identifiers = identifiers_for combinations
222
226
 
223
227
  # Assume it's using EVALSHA.
224
228
  #
@@ -256,9 +260,7 @@ module Picky
256
260
  #
257
261
  module NonScripting
258
262
  def ids combinations, amount, offset
259
- identifiers = combinations.inject([]) do |identifiers, combination|
260
- identifiers << "#{combination.identifier}"
261
- end
263
+ identifiers = identifiers_for combinations
262
264
 
263
265
  result_id = generate_intermediate_result_id
264
266
 
@@ -3,35 +3,33 @@
3
3
  class Module
4
4
 
5
5
  def forward *methods
6
- to = extract_to_from_options methods,
7
- "Forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. forward :something, :to => :an_array_reader)."
8
- forwarding methods do |method|
9
- "def #{method}(*args, &block)\n#{to}.__send__(#{method.inspect}, *args, &block)\nend\n"
10
- end
6
+ forwarding methods,
7
+ 'def %{method}(*args, &block); %{to}.__send__(:%{method}, *args, &block); end',
8
+ 'Forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. forward :something, :to => :a_reader).'
11
9
  end
12
10
 
13
11
  def each_forward *methods
14
- to = extract_to_from_options methods,
15
- "Multi forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. each_forward :something, :to => :an_array_reader)."
16
- forwarding methods do |method|
17
- "def #{method}(*args, &block)\n#{to}.each{ |t| t.__send__(#{method.inspect}, *args, &block) }\nend\n"
18
- end
12
+ forwarding methods,
13
+ 'def %{method}(*args, &block); %{to}.each{ |t| t.__send__(:%{method}, *args, &block) }; end',
14
+ 'Multi forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. each_forward :something, :to => :an_array_reader).'
19
15
  end
20
16
 
21
17
  private
22
18
 
23
- def extract_to_from_options args, error_string
19
+ def forwarding methods, method_definition_template, error_message = nil
20
+ to = extract_to_from_options methods, error_message
21
+ methods.each do |method|
22
+ method_definition = method_definition_template % { to: to, method: method }
23
+ module_eval method_definition, "(__FORWARDING__)", 1
24
+ end
25
+ end
26
+
27
+ def extract_to_from_options args, error_message
24
28
  options = args.pop
25
29
  unless options.is_a?(Hash) && to = options[:to]
26
- raise ArgumentError, "Multi forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. each_forward :something, :to => :an_array_reader)."
30
+ raise ArgumentError, error_message
27
31
  end
28
32
  to
29
33
  end
30
-
31
- def forwarding methods, &method_definition
32
- methods.each do |method|
33
- module_eval method_definition[method], "(__FORWARDING__)", 1
34
- end
35
- end
36
34
 
37
35
  end
@@ -61,23 +61,12 @@ module Picky
61
61
 
62
62
  # Optimized, therefore duplicate code.
63
63
  #
64
- # TODO Deoptimize?
65
- #
66
- if tokenizer
67
- objects.each do |object|
68
- tokens, _ = tokenizer.tokenize object.send(category.from) # Note: Originals not needed.
69
- tokens.each do |token_text|
70
- next unless token_text
71
- cache << object.id << comma << token_text << newline
72
- end
73
- end
74
- else
75
- objects.each do |object|
76
- tokens = object.send(category.from) # Note: Originals not needed.
77
- tokens.each do |token_text|
78
- next unless token_text
79
- cache << object.id << comma << token_text << newline
80
- end
64
+ objects.each do |object|
65
+ tokens = object.send category.from
66
+ tokens, _ = tokenizer.tokenize tokens if tokenizer # Note: Originals not needed. TODO Optimize?
67
+ tokens.each do |token_text|
68
+ next unless token_text
69
+ cache << object.id << comma << token_text << newline
81
70
  end
82
71
  end
83
72
 
data/lib/picky/loader.rb CHANGED
@@ -55,7 +55,7 @@ module Picky
55
55
  # when installing the gem.
56
56
  #
57
57
  def load_c_code
58
- require_relative '../maybe_compile'
58
+ require_relative '../try_compile'
59
59
  end
60
60
  def load_extensions
61
61
  load_relative 'extensions/object',
@@ -0,0 +1,24 @@
1
+ begin
2
+ require ::File.expand_path '../picky/picky', __FILE__
3
+ rescue LoadError => e
4
+ # Give up and inform the user.
5
+ #
6
+ puts <<-NOTE
7
+
8
+ Picky tried to compile its source on your system but failed.
9
+
10
+ If you are trying to develop for it, please run the specs first:
11
+ bundle exec rake
12
+ (You might need to set ulimit -n 3000 for the tests to run)
13
+
14
+ Please add an issue: https://github.com/floere/picky/issues/
15
+ and copy anything into it that you think is helpful. Thanks!
16
+
17
+ See related issue: https://github.com/floere/picky/issues/81
18
+
19
+ The problem reported by the compiler was:
20
+ #{e}
21
+
22
+ NOTE
23
+ exit 1
24
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe 'Category#tokenize(false)' do
6
+
7
+ it 'does tokenize' do
8
+ index = Picky::Index.new :thing do
9
+ category :text, tokenize: true
10
+ end
11
+
12
+ thing = Struct.new :id, :text
13
+ index.add thing.new(1, ['already', 'tokenized']) # Does not fail – because #to_s is called on the Array.
14
+ index.add thing.new(2, 'this should not fail')
15
+
16
+ try = Picky::Search.new index
17
+ try.search('already').ids.should == [] # Not found because ["already", is indexed.
18
+ try.search('should').ids.should == [2]
19
+ end
20
+ it 'does tokenize (default)' do
21
+ index = Picky::Index.new :thing do
22
+ category :text
23
+ end
24
+
25
+ thing = Struct.new :id, :text
26
+ # expect do # Does not fail – because #to_s is called on the Array.
27
+ index.add thing.new(1, ['already', 'tokenized'])
28
+ # end.to raise_error
29
+ index.add thing.new(2, 'this should not fail')
30
+
31
+ try = Picky::Search.new index
32
+
33
+ try.search('already').ids.should == [] # Not found because ['already', is indexed.
34
+ end
35
+ it 'does not tokenize' do
36
+ index = Picky::Index.new :thing do
37
+ category :text, tokenize: false
38
+ end
39
+
40
+ thing = Struct.new :id, :text
41
+ index.add thing.new(1, ['already', 'tokenized'])
42
+ expect do
43
+ index.add thing.new(2, 'this should fail')
44
+ end.to raise_error('You probably set tokenize: false on category "text". It will need an Enumerator of previously tokenized tokens.')
45
+
46
+ try = Picky::Search.new index
47
+
48
+ try.search('already').ids.should == [1]
49
+ end
50
+ it 'does not tokenize and indexes correctly' do
51
+ index = Picky::Index.new :thing do
52
+ category :text, tokenize: false
53
+ end
54
+
55
+ thing = Struct.new :id, :text
56
+ index.add thing.new(1, ['already', 'tokenized'])
57
+ expect do
58
+ index.add thing.new(2, 'this should fail')
59
+ end.to raise_error('You probably set tokenize: false on category "text". It will need an Enumerator of previously tokenized tokens.')
60
+
61
+ try = Picky::Search.new index
62
+
63
+ try.search('already').ids.should == [1]
64
+ end
65
+
66
+ end
@@ -28,7 +28,7 @@ describe 'GC stats: searching' do
28
28
  end
29
29
  let(:search) { Picky::Search.new data }
30
30
 
31
- # TODO Study what the problem is.
31
+ # TODO Why are both versions almost equally fast?
32
32
  #
33
33
  context 'without pool' do
34
34
  it 'runs the GC more' do
@@ -40,14 +40,14 @@ describe 'GC stats: searching' do
40
40
  query = 'abracadabra mirgel'
41
41
  gc_runs_of do
42
42
  amount.times { try.search query }
43
- end.should <= 13
43
+ end.should >= 10
44
44
  end
45
45
  it 'is less (?) performant' do
46
46
  try = search
47
47
  query = 'abracadabra mirgel'
48
48
  performance_of do
49
49
  amount.times { try.search query }
50
- end.should <= 0.42
50
+ end.should >= 0.15
51
51
  end
52
52
  end
53
53
  context 'with pool' do
@@ -67,7 +67,10 @@ describe 'GC stats: searching' do
67
67
  try = search
68
68
  query = 'abracadabra mirgel'
69
69
  gc_runs_of do
70
- amount.times { try.search query; Picky::Pool.release_all }
70
+ amount.times do
71
+ try.search query
72
+ Picky::Pool.release_all
73
+ end
71
74
  end.should <= 1 # Definitely less GC runs.
72
75
  end
73
76
  it 'is more (?) performant' do
@@ -75,7 +78,7 @@ describe 'GC stats: searching' do
75
78
  query = 'abracadabra mirgel'
76
79
  performance_of do
77
80
  amount.times { try.search query }
78
- end.should <= 0.42
81
+ end.should <= 0.2
79
82
  end
80
83
  end
81
84
 
@@ -67,7 +67,14 @@ describe Module do
67
67
  Class.new do
68
68
  forward :bli, :bla, :blu # :to missing
69
69
  end
70
- end.should raise_error(ArgumentError)
70
+ end.should raise_error(ArgumentError, "Forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. forward :something, :to => :a_reader).")
71
+ end
72
+ it 'should raise an error' do
73
+ lambda do
74
+ Class.new do
75
+ each_forward :bli, :bla, :blu # :to missing
76
+ end
77
+ end.should raise_error(ArgumentError, "Multi forwarding needs a target. Supply an options hash with a :to key as the last argument (e.g. each_forward :something, :to => :an_array_reader).")
71
78
  end
72
79
  end
73
80
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picky
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.14.0
4
+ version: 4.15.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-02 00:00:00.000000000 Z
12
+ date: 2013-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70147105922620 !ruby/object:Gem::Requirement
16
+ requirement: &70116179207700 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,21 +21,32 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70147105922620
24
+ version_requirements: *70116179207700
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake-compiler
27
+ requirement: &70116179229800 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70116179229800
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: picky-client
27
- requirement: &70147105922020 !ruby/object:Gem::Requirement
38
+ requirement: &70116179229120 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
31
42
  - !ruby/object:Gem::Version
32
- version: 4.14.0
43
+ version: 4.15.0
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *70147105922020
46
+ version_requirements: *70116179229120
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: text
38
- requirement: &70147105921540 !ruby/object:Gem::Requirement
49
+ requirement: &70116179228440 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '0'
44
55
  type: :runtime
45
56
  prerelease: false
46
- version_requirements: *70147105921540
57
+ version_requirements: *70116179228440
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: multi_json
49
- requirement: &70147105921060 !ruby/object:Gem::Requirement
60
+ requirement: &70116179227980 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: '0'
55
66
  type: :runtime
56
67
  prerelease: false
57
- version_requirements: *70147105921060
68
+ version_requirements: *70116179227980
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: activesupport
60
- requirement: &70147105920460 !ruby/object:Gem::Requirement
71
+ requirement: &70116179227480 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '3.0'
66
77
  type: :runtime
67
78
  prerelease: false
68
- version_requirements: *70147105920460
79
+ version_requirements: *70116179227480
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: rack_fast_escape
71
- requirement: &70147105919900 !ruby/object:Gem::Requirement
82
+ requirement: &70116179227040 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,18 +87,16 @@ dependencies:
76
87
  version: '0'
77
88
  type: :runtime
78
89
  prerelease: false
79
- version_requirements: *70147105919900
90
+ version_requirements: *70116179227040
80
91
  description: Fast Ruby semantic text search engine with comfortable single field interface.
81
92
  email: florian.hanke+picky@gmail.com
82
93
  executables:
83
94
  - picky
84
95
  extensions:
85
- - lib/extconf.rb
96
+ - ext/picky/extconf.rb
86
97
  extra_rdoc_files: []
87
98
  files:
88
99
  - aux/picky/cli.rb
89
- - lib/extconf.rb
90
- - lib/maybe_compile.rb
91
100
  - lib/picky/analytics.rb
92
101
  - lib/picky/analyzer.rb
93
102
  - lib/picky/api/search/boost.rb
@@ -224,6 +233,7 @@ files:
224
233
  - lib/picky/wrappers/bundle/wrapper.rb
225
234
  - lib/picky.rb
226
235
  - lib/tasks/try.rb
236
+ - lib/try_compile.rb
227
237
  - lib/tasks/application.rake
228
238
  - lib/tasks/framework.rake
229
239
  - lib/tasks/index.rake
@@ -231,7 +241,7 @@ files:
231
241
  - lib/tasks/statistics.rake
232
242
  - lib/tasks/todo.rake
233
243
  - lib/tasks/try.rake
234
- - lib/performant.c
244
+ - ext/picky/picky.c
235
245
  - spec/aux/picky/cli_spec.rb
236
246
  - spec/functional/allocations_uniq_by_definition_spec.rb
237
247
  - spec/functional/automatic_segmentation_spec.rb
@@ -239,7 +249,6 @@ files:
239
249
  - spec/functional/backends/memory_bundle_realtime_spec.rb
240
250
  - spec/functional/backends/memory_json_utf8_spec.rb
241
251
  - spec/functional/backends/memory_spec.rb
242
- - spec/functional/backends/no_tokenize_spec.rb
243
252
  - spec/functional/backends/redis_bundle_realtime_spec.rb
244
253
  - spec/functional/backends/redis_spec.rb
245
254
  - spec/functional/backends/special_spec.rb
@@ -254,6 +263,7 @@ files:
254
263
  - spec/functional/ignore_spec.rb
255
264
  - spec/functional/max_allocations_spec.rb
256
265
  - spec/functional/multi_index_qualifier_spec.rb
266
+ - spec/functional/no_tokenize_spec.rb
257
267
  - spec/functional/non_specific_ids_larger_than_20_spec.rb
258
268
  - spec/functional/only_spec.rb
259
269
  - spec/functional/pool_spec.rb
@@ -376,6 +386,7 @@ files:
376
386
  - spec/lib/tokenizer_spec.rb
377
387
  - spec/performant_spec.rb
378
388
  - bin/picky
389
+ - ext/picky/extconf.rb
379
390
  homepage: http://florianhanke.com/picky
380
391
  licenses: []
381
392
  post_install_message:
@@ -408,7 +419,6 @@ test_files:
408
419
  - spec/functional/backends/memory_bundle_realtime_spec.rb
409
420
  - spec/functional/backends/memory_json_utf8_spec.rb
410
421
  - spec/functional/backends/memory_spec.rb
411
- - spec/functional/backends/no_tokenize_spec.rb
412
422
  - spec/functional/backends/redis_bundle_realtime_spec.rb
413
423
  - spec/functional/backends/redis_spec.rb
414
424
  - spec/functional/backends/special_spec.rb
@@ -423,6 +433,7 @@ test_files:
423
433
  - spec/functional/ignore_spec.rb
424
434
  - spec/functional/max_allocations_spec.rb
425
435
  - spec/functional/multi_index_qualifier_spec.rb
436
+ - spec/functional/no_tokenize_spec.rb
426
437
  - spec/functional/non_specific_ids_larger_than_20_spec.rb
427
438
  - spec/functional/only_spec.rb
428
439
  - spec/functional/pool_spec.rb
data/lib/maybe_compile.rb DELETED
@@ -1,40 +0,0 @@
1
- # Note: This is handled toplevel (in the file
2
- # structure) to not confuse compilers.
3
- #
4
- failed = 0
5
-
6
- begin
7
- require ::File.expand_path '../performant', __FILE__
8
- rescue LoadError => e
9
- failed += 1
10
-
11
- # Have Makefile built.
12
- #
13
- require ::File.expand_path '../extconf', __FILE__
14
-
15
- # Run make in the right gem directory.
16
- #
17
- Dir.chdir(::File.expand_path '..', __FILE__) do
18
- puts %x(make)
19
- end
20
-
21
- # Try again.
22
- #
23
- retry if failed < 2
24
-
25
- # Give up and inform the user.
26
- #
27
- puts <<-NOTE
28
-
29
- Picky tried to compile its source on your system but failed.
30
- Please add an issue: https://github.com/floere/picky/issues/
31
- and copy anything into it that you think is helpful. Thanks!
32
-
33
- See related issue: https://github.com/floere/picky/issues/81
34
-
35
- The problem reported by the compiler was:
36
- #{e}
37
-
38
- NOTE
39
- exit 1
40
- end
@@ -1,38 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- require 'spec_helper'
4
-
5
- describe 'Category#tokenize(false)' do
6
-
7
- it 'does tokenize' do
8
- index = Picky::Index.new :thing do
9
- category :text, tokenize: true
10
- end
11
-
12
- thing = Struct.new :id, :text
13
- # expect do # Does not fail – because #to_s is called on the Array.
14
- index.add thing.new(1, ['already', 'tokenized'])
15
- # end.to raise_error
16
- index.add thing.new(2, 'this should fail')
17
-
18
- try = Picky::Search.new index
19
-
20
- try.search('already').ids.should == [] # Not found because ['already', is indexed.
21
- end
22
- it 'does not tokenize' do
23
- index = Picky::Index.new :thing do
24
- category :text, tokenize: false
25
- end
26
-
27
- thing = Struct.new :id, :text
28
- index.add thing.new(1, ['already', 'tokenized'])
29
- expect do
30
- index.add thing.new(2, 'this should fail')
31
- end.to raise_error('You probably set tokenize: false on category "text". It will need an Enumerator of previously tokenized tokens.')
32
-
33
- try = Picky::Search.new index
34
-
35
- try.search('already').ids.should == [1]
36
- end
37
-
38
- end