picky 4.6.3 → 4.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/lib/performant.c +4 -4
  2. data/lib/picky/analyzer.rb +6 -3
  3. data/lib/picky/backends/backend.rb +40 -0
  4. data/lib/picky/backends/file/json.rb +4 -0
  5. data/lib/picky/backends/file.rb +1 -25
  6. data/lib/picky/backends/memory/json.rb +4 -0
  7. data/lib/picky/backends/memory.rb +1 -29
  8. data/lib/picky/backends/redis/directly_manipulable.rb +15 -7
  9. data/lib/picky/backends/redis.rb +91 -92
  10. data/lib/picky/backends/sqlite/basic.rb +6 -0
  11. data/lib/picky/bundle.rb +12 -10
  12. data/lib/picky/categories_indexing.rb +0 -13
  13. data/lib/picky/category.rb +24 -21
  14. data/lib/picky/category_indexing.rb +8 -22
  15. data/lib/picky/constants.rb +0 -1
  16. data/lib/picky/generators/aliases.rb +2 -0
  17. data/lib/picky/generators/partial.rb +27 -0
  18. data/lib/picky/generators/similarity.rb +27 -0
  19. data/lib/picky/generators/weights.rb +32 -0
  20. data/lib/picky/helpers/identification.rb +18 -0
  21. data/lib/picky/helpers/indexing.rb +16 -0
  22. data/lib/picky/index.rb +6 -0
  23. data/lib/picky/index_indexing.rb +9 -21
  24. data/lib/picky/indexes_indexing.rb +5 -14
  25. data/lib/picky/loader.rb +204 -199
  26. data/lib/picky/query/indexes.rb +12 -1
  27. data/lib/picky/search.rb +1 -0
  28. data/lib/picky/source.rb +23 -0
  29. data/lib/picky/tokenizer.rb +35 -13
  30. data/spec/functional/facets_spec.rb +1 -1
  31. data/spec/functional/remap_qualifiers_spec.rb +43 -0
  32. data/spec/functional/tokenizer_spec.rb +1 -1
  33. data/spec/lib/api/search/boost_spec.rb +1 -1
  34. data/spec/lib/category_spec.rb +1 -4
  35. data/spec/lib/generators/partial_spec.rb +58 -0
  36. data/spec/lib/generators/similarity_spec.rb +59 -0
  37. data/spec/lib/generators/weights_spec.rb +68 -0
  38. data/spec/lib/index_indexing_spec.rb +2 -4
  39. data/spec/lib/index_spec.rb +6 -0
  40. data/spec/lib/pool_spec.rb +39 -35
  41. data/spec/lib/sinatra_spec.rb +2 -2
  42. data/spec/lib/source_spec.rb +63 -0
  43. data/spec/lib/tokenizer_spec.rb +64 -2
  44. metadata +20 -20
  45. data/lib/picky/api/category/partial.rb +0 -26
  46. data/lib/picky/api/category/similarity.rb +0 -26
  47. data/lib/picky/api/category/weight.rb +0 -28
  48. data/lib/picky/api/source.rb +0 -35
  49. data/lib/picky/api/tokenizer.rb +0 -37
  50. data/lib/picky/deployment.rb +0 -211
  51. data/spec/lib/api/category/partial_spec.rb +0 -49
  52. data/spec/lib/api/category/similarity_spec.rb +0 -50
  53. data/spec/lib/api/category/weight_spec.rb +0 -55
  54. data/spec/lib/api/source_spec.rb +0 -68
  55. data/spec/lib/api/tokenizer_spec.rb +0 -42
data/lib/performant.c CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // Copying internal ruby methods.
4
4
  //
5
- inline VALUE rb_ary_elt(ary, offset)
5
+ static inline VALUE rb_ary_elt(ary, offset)
6
6
  VALUE ary;
7
7
  long offset;
8
8
  {
@@ -12,7 +12,7 @@ inline VALUE rb_ary_elt(ary, offset)
12
12
  }
13
13
  return RARRAY_PTR(ary)[offset];
14
14
  }
15
- inline VALUE ary_make_hash(ary1, ary2)
15
+ static inline VALUE ary_make_hash(ary1, ary2)
16
16
  VALUE ary1, ary2;
17
17
  {
18
18
  VALUE hash = rb_hash_new();
@@ -28,7 +28,7 @@ inline VALUE ary_make_hash(ary1, ary2)
28
28
  }
29
29
  return hash;
30
30
  }
31
- inline VALUE rb_ary_length(VALUE ary) {
31
+ static inline VALUE rb_ary_length(VALUE ary) {
32
32
  long length = RARRAY_LEN(ary);
33
33
  return LONG2NUM(length);
34
34
  }
@@ -37,7 +37,7 @@ inline VALUE rb_ary_length(VALUE ary) {
37
37
  // * orders the arrays by ascending size, small to large.
38
38
  // * calls the & consecutively for all arrays.
39
39
  //
40
- inline VALUE memory_efficient_intersect(VALUE self, VALUE unsorted_array_of_arrays) {
40
+ static inline VALUE memory_efficient_intersect(VALUE self, VALUE unsorted_array_of_arrays) {
41
41
  // Counters.
42
42
  //
43
43
  long i, j;
@@ -135,17 +135,20 @@ class Analyzer
135
135
  return if analysis[:__keys].zero?
136
136
  ary = ["index key cardinality: #{"%10d" % analysis[:__keys]}"]
137
137
  return ary.join "\n" unless analysis[:index]
138
- ary << "index key length range (avg): #{"%10s" % analysis[:index][:key_length]} (#{analysis[:index][:key_length_average].round(2)})"
139
- ary << "index ids per key length range (avg): #{"%10s" % analysis[:index][:ids_length]} (#{analysis[:index][:ids_length_average].round(2)})"
138
+ ary << formatted('', :key_length)
139
+ ary << formatted('ids per', :ids_length)
140
140
  ary.join "\n"
141
141
  end
142
+ def formatted description, key, index = :index
143
+ "index #{description} key length range (avg): #{"%10s" % analysis[index][key]} (#{analysis[index][:"#{key}_average"].round(2)})"
144
+ end
142
145
  def weights_to_s
143
146
  return unless analysis[:weights]
144
147
  %Q{weights range (avg): #{"%10s" % analysis[:weights][:weight_range]} (#{analysis[:weights][:weight_average].round(2)})}
145
148
  end
146
149
  def similarity_to_s
147
150
  return unless analysis[:similarity]
148
- %Q{similarity key length range (avg): #{"%10s" % analysis[:similarity][:key_length]} (#{analysis[:similarity][:key_length_average].round(2)})}
151
+ formatted('similarity', :key_length, :similarity)
149
152
  end
150
153
  def configuration_to_s
151
154
  # analysis[:configuration]
@@ -5,6 +5,46 @@ module Picky
5
5
  #
6
6
  #
7
7
  class Backend
8
+
9
+ # This is the default behaviour and should be overridden
10
+ # for different backends.
11
+ #
12
+
13
+ # Returns an object that on #initial, #load returns
14
+ # an object that responds to:
15
+ # [:token] # => [id, id, id, id, id] (an array of ids)
16
+ #
17
+ def create_inverted bundle
18
+ json bundle.index_path(:inverted)
19
+ end
20
+ # Returns an object that on #initial, #load returns
21
+ # an object that responds to:
22
+ # [:token] # => 1.23 (a weight)
23
+ #
24
+ def create_weights bundle
25
+ json bundle.index_path(:weights)
26
+ end
27
+ # # Returns an object that on #initial, #load returns
28
+ # # an object that responds to:
29
+ # # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
30
+ # #
31
+ # def create_similarity bundle
32
+ # Marshal.new bundle.index_path(:similarity)
33
+ # end
34
+ # Returns an object that on #initial, #load returns
35
+ # an object that responds to:
36
+ # [:key] # => value (a value for this config key)
37
+ #
38
+ def create_configuration bundle
39
+ json bundle.index_path(:configuration)
40
+ end
41
+ # Returns an object that on #initial, #load returns
42
+ # an object that responds to:
43
+ # [id] # => [:sym1, :sym2]
44
+ #
45
+ def create_realtime bundle
46
+ json bundle.index_path(:realtime)
47
+ end
8
48
 
9
49
  # Returns the total score of the combinations.
10
50
  #
@@ -3,6 +3,10 @@ module Picky
3
3
  module Backends
4
4
 
5
5
  class File
6
+
7
+ def json *args
8
+ JSON.new *args
9
+ end
6
10
 
7
11
  # File-based index files dumped in the JSON format.
8
12
  #
@@ -10,35 +10,11 @@ module Picky
10
10
  #
11
11
  class File < Backend
12
12
 
13
- # Returns an object that on #initial, #load returns an object that responds to:
14
- # [:token] # => [id, id, id, id, id] (an array of ids)
15
- #
16
- def create_inverted bundle
17
- JSON.new bundle.index_path(:inverted)
18
- end
19
- # Returns an object that on #initial, #load returns an object that responds to:
20
- # [:token] # => 1.23 (a weight)
21
- #
22
- def create_weights bundle
23
- JSON.new bundle.index_path(:weights)
24
- end
25
13
  # Returns an object that on #initial, #load returns an object that responds to:
26
14
  # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
27
15
  #
28
16
  def create_similarity bundle
29
- JSON.new bundle.index_path(:similarity)
30
- end
31
- # Returns an object that on #initial, #load returns an object that responds to:
32
- # [:key] # => value (a value for this config key)
33
- #
34
- def create_configuration bundle
35
- JSON.new bundle.index_path(:configuration)
36
- end
37
- # Returns an object that on #initial, #load returns an object that responds to:
38
- # [id] # => [:sym1, :sym2]
39
- #
40
- def create_realtime bundle
41
- JSON.new bundle.index_path(:realtime)
17
+ json bundle.index_path(:similarity)
42
18
  end
43
19
 
44
20
  end
@@ -3,6 +3,10 @@ module Picky
3
3
  module Backends
4
4
 
5
5
  class Memory
6
+
7
+ def json *args
8
+ JSON.new *args
9
+ end
6
10
 
7
11
  # Memory-based index files dumped in the JSON format.
8
12
  #
@@ -3,21 +3,7 @@ module Picky
3
3
  module Backends
4
4
 
5
5
  class Memory < Backend
6
-
7
- # Returns an object that on #initial, #load returns
8
- # an object that responds to:
9
- # [:token] # => [id, id, id, id, id] (an array of ids)
10
- #
11
- def create_inverted bundle
12
- JSON.new bundle.index_path(:inverted)
13
- end
14
- # Returns an object that on #initial, #load returns
15
- # an object that responds to:
16
- # [:token] # => 1.23 (a weight)
17
- #
18
- def create_weights bundle
19
- JSON.new bundle.index_path(:weights)
20
- end
6
+
21
7
  # Returns an object that on #initial, #load returns
22
8
  # an object that responds to:
23
9
  # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
@@ -25,20 +11,6 @@ module Picky
25
11
  def create_similarity bundle
26
12
  Marshal.new bundle.index_path(:similarity)
27
13
  end
28
- # Returns an object that on #initial, #load returns
29
- # an object that responds to:
30
- # [:key] # => value (a value for this config key)
31
- #
32
- def create_configuration bundle
33
- JSON.new bundle.index_path(:configuration)
34
- end
35
- # Returns an object that on #initial, #load returns
36
- # an object that responds to:
37
- # [id] # => [:sym1, :sym2]
38
- #
39
- def create_realtime bundle
40
- JSON.new bundle.index_path(:realtime)
41
- end
42
14
 
43
15
  end
44
16
 
@@ -18,25 +18,33 @@ module Picky
18
18
  #
19
19
  @@append_index = 0
20
20
  def << value
21
- super value
22
- backend.client.zadd "#{backend.namespace}:#{key}", (@@append_index+=1), value
23
- backend[key]
21
+ super
22
+ zadd value, @@append_index+=1
24
23
  end
25
24
 
26
25
  # THINK Current implementation is very brittle.
27
26
  #
28
27
  @@unshift_index = 0
29
28
  def unshift value
30
- super value
31
- backend.client.zadd "#{backend.namespace}:#{key}", (@@unshift_index-=1), value
32
- backend[key]
29
+ super
30
+ zadd value, @@unshift_index -= 1
33
31
  end
34
-
32
+
33
+ # Deletes the value.
34
+ #
35
35
  def delete value
36
36
  result = super value
37
37
  backend.client.zrem "#{backend.namespace}:#{key}", value if result
38
38
  result
39
39
  end
40
+
41
+ # Z-Adds a value with the given index.
42
+ #
43
+ def zadd value, index
44
+ backend.client.zadd "#{backend.namespace}:#{key}", index, value
45
+ backend[key]
46
+ end
47
+
40
48
  end
41
49
 
42
50
  end
@@ -169,104 +169,24 @@ module Picky
169
169
  require 'digest/sha1'
170
170
  @@ids_sent_once = nil
171
171
 
172
- # Scripting version of #ids.
172
+ # Overrides _this_ method.
173
173
  #
174
- class << self
175
- def ids combinations, amount, offset
176
- identifiers = combinations.inject([]) do |identifiers, combination|
177
- identifiers << "#{combination.identifier}"
178
- end
179
-
180
- # Assume it's using EVALSHA.
181
- #
182
- begin
183
- if identifiers.size > 1
184
- client.evalsha @@ids_sent_once,
185
- identifiers.size,
186
- *identifiers,
187
- generate_intermediate_result_id,
188
- offset,
189
- (offset + amount)
190
- else
191
- client.zrange identifiers.first,
192
- offset,
193
- (offset + amount)
194
- end
195
- rescue RuntimeError => e
196
- # Make the server have a SHA-1 for the script.
197
- #
198
- @@ids_sent_once = Digest::SHA1.hexdigest @@ids_script
199
- client.eval @@ids_script,
200
- identifiers.size,
201
- *identifiers,
202
- generate_intermediate_result_id,
203
- offset,
204
- (offset + amount)
205
- end
206
- end
207
- end
174
+ extend Scripting
208
175
  else
209
- # Non-Scripting version of #ids.
176
+ # Overrides _this_ method.
210
177
  #
211
- class << self
212
- def ids combinations, amount, offset
213
- identifiers = combinations.inject([]) do |identifiers, combination|
214
- identifiers << "#{combination.identifier}"
215
- end
216
-
217
- result_id = generate_intermediate_result_id
218
-
219
- # Little optimization.
220
- #
221
- if identifiers.size > 1
222
- # Intersect and store.
223
- #
224
- intersected = client.zinterstore result_id, identifiers
225
-
226
- # Return clean and early if there has been no intersection.
227
- #
228
- if intersected.zero?
229
- client.del result_id
230
- return []
231
- end
232
-
233
- # Get the stored result.
234
- #
235
- results = client.zrange result_id, offset, (offset + amount)
236
-
237
- # Delete the stored result as it was only for temporary purposes.
238
- #
239
- # Note: I could also not delete it, but that
240
- # would not be clean at all.
241
- #
242
- client.del result_id
243
- else
244
- results = client.zrange identifiers.first, offset, (offset + amount)
245
- end
246
-
247
- results
248
- end
249
- end
178
+ extend NonScripting
250
179
  end
251
180
  else
252
- class << self
253
- def ids combinations, _, _
254
- # Get the ids for each combination.
255
- #
256
- id_arrays = combinations.inject([]) do |total, combination|
257
- total << combination.ids
258
- end
259
-
260
- # Call the optimized C algorithm.
261
- #
262
- # Note: It orders the passed arrays by size.
263
- #
264
- Performant::Array.memory_efficient_intersect id_arrays
265
- end
266
- end
181
+ # Remove _this_ method and use the super
182
+ # class method from now on.
183
+ #
184
+ # Note: This fails if there are multiple
185
+ # Redis backends with different versions.
186
+ #
187
+ self.class.send :remove_method, __method__
267
188
  end
268
-
269
- # Call the newly installed version.
189
+ # Call the newly installed / super class version.
270
190
  #
271
191
  ids combinations, amount, offset
272
192
  end
@@ -291,6 +211,85 @@ module Picky
291
211
  def generate_intermediate_result_id
292
212
  @intermediate_result_id ||= "#{host}:#{pid}:picky:result"
293
213
  end
214
+
215
+ # Uses Lua scripting on Redis 2.6.
216
+ #
217
+ module Scripting
218
+ def ids combinations, amount, offset
219
+ identifiers = combinations.inject([]) do |identifiers, combination|
220
+ identifiers << "#{combination.identifier}"
221
+ end
222
+
223
+ # Assume it's using EVALSHA.
224
+ #
225
+ begin
226
+ if identifiers.size > 1
227
+ client.evalsha @@ids_sent_once,
228
+ identifiers.size,
229
+ *identifiers,
230
+ generate_intermediate_result_id,
231
+ offset,
232
+ (offset + amount)
233
+ else
234
+ client.zrange identifiers.first,
235
+ offset,
236
+ (offset + amount)
237
+ end
238
+ rescue RuntimeError => e
239
+ # Make the server have a SHA-1 for the script.
240
+ #
241
+ @@ids_sent_once = Digest::SHA1.hexdigest @@ids_script
242
+ client.eval @@ids_script,
243
+ identifiers.size,
244
+ *identifiers,
245
+ generate_intermediate_result_id,
246
+ offset,
247
+ (offset + amount)
248
+ end
249
+ end
250
+ end
251
+
252
+ # Does not use Lua scripting, < Redis 2.6.
253
+ #
254
+ module NonScripting
255
+ def ids combinations, amount, offset
256
+ identifiers = combinations.inject([]) do |identifiers, combination|
257
+ identifiers << "#{combination.identifier}"
258
+ end
259
+
260
+ result_id = generate_intermediate_result_id
261
+
262
+ # Little optimization.
263
+ #
264
+ if identifiers.size > 1
265
+ # Intersect and store.
266
+ #
267
+ intersected = client.zinterstore result_id, identifiers
268
+
269
+ # Return clean and early if there has been no intersection.
270
+ #
271
+ if intersected.zero?
272
+ client.del result_id
273
+ return []
274
+ end
275
+
276
+ # Get the stored result.
277
+ #
278
+ results = client.zrange result_id, offset, (offset + amount)
279
+
280
+ # Delete the stored result as it was only for temporary purposes.
281
+ #
282
+ # Note: I could also not delete it, but that
283
+ # would not be clean at all.
284
+ #
285
+ client.del result_id
286
+ else
287
+ results = client.zrange identifiers.first, offset, (offset + amount)
288
+ end
289
+
290
+ results
291
+ end
292
+ end
294
293
 
295
294
  end
296
295
 
@@ -17,6 +17,12 @@ module Picky
17
17
  @realtime = options[:realtime]
18
18
 
19
19
  lazily_initialize_client
20
+
21
+ # Note: If on OSX, too many files get opened during
22
+ # the specs -> ulimit -n 3000
23
+ #
24
+ # rescue SQLite3::CantOpenException => e
25
+ #
20
26
  end
21
27
 
22
28
  def initial
data/lib/picky/bundle.rb CHANGED
@@ -91,22 +91,24 @@ module Picky
91
91
  # the strategy itself pretends to be an index.
92
92
  #
93
93
  def initialize_backends
94
- @inverted = @backend_inverted.initial
95
- @weights = @weight_strategy.respond_to?(:saved?) && !@weight_strategy.saved? ? @weight_strategy : @backend_weights.initial
96
- @similarity = @backend_similarity.initial
97
- @configuration = @backend_configuration.initial
98
- @realtime = @backend_realtime.initial
94
+ on_all_indexes_call :initial
99
95
  end
100
96
 
101
97
  # "Empties" the index(es) by getting a new empty
102
98
  # internal backend instance.
103
99
  #
104
100
  def empty
105
- @inverted = @backend_inverted.empty
106
- @weights = @weight_strategy.respond_to?(:saved?) && !@weight_strategy.saved? ? @weight_strategy : @backend_weights.empty
107
- @similarity = @backend_similarity.empty
108
- @configuration = @backend_configuration.empty
109
- @realtime = @backend_realtime.empty
101
+ on_all_indexes_call :empty
102
+ end
103
+
104
+ # Extracted to avoid duplicate code.
105
+ #
106
+ def on_all_indexes_call method_name
107
+ @inverted = @backend_inverted.send method_name
108
+ @weights = @weight_strategy.respond_to?(:saved?) && !@weight_strategy.saved? ? @weight_strategy : @backend_weights.send(method_name)
109
+ @similarity = @backend_similarity.send method_name
110
+ @configuration = @backend_configuration.send method_name
111
+ @realtime = @backend_realtime.send method_name
110
112
  end
111
113
 
112
114
  # Delete all index files.
@@ -8,19 +8,6 @@ module Picky
8
8
  :clear,
9
9
  :prepare,
10
10
  :to => :categories
11
-
12
- # First prepares all categories,
13
- # then caches all categories.
14
- #
15
- def index scheduler = Scheduler.new
16
- timed_indexing scheduler do
17
- categories.prepare scheduler
18
- scheduler.finish
19
-
20
- categories.cache scheduler
21
- scheduler.finish
22
- end
23
- end
24
11
  end
25
12
 
26
13
  end
@@ -3,10 +3,6 @@ module Picky
3
3
  class Category
4
4
 
5
5
  include API::Tokenizer
6
- include API::Source
7
- include API::Category::Weight
8
- include API::Category::Partial
9
- include API::Category::Similarity
10
6
 
11
7
  attr_accessor :exact,
12
8
  :partial
@@ -40,11 +36,17 @@ module Picky
40
36
  @name = name
41
37
  @index = index
42
38
 
43
- # Indexing.
44
- #
45
- @source = extract_source options[:source], nil_ok: true
39
+ configure_from options
40
+ configure_indexes_from options
41
+ end
42
+
43
+ def configure_from options
46
44
  @from = options[:from]
47
- @tokenizer = extract_tokenizer options[:indexing]
45
+
46
+ # Instantly extracted to raise an error instantly.
47
+ #
48
+ @source = Source.from options[:source], true, @index.name
49
+ @tokenizer = Tokenizer.from options[:indexing], @index.name, name
48
50
 
49
51
  @key_format = options.delete :key_format
50
52
  @backend = options.delete :backend
@@ -52,10 +54,16 @@ module Picky
52
54
  @qualifiers = extract_qualifiers_from options
53
55
 
54
56
  # @symbols = options[:use_symbols] || index.use_symbols? # SYMBOLS.
57
+ end
55
58
 
56
- weights = extract_weight options[:weight]
57
- partial = extract_partial options[:partial]
58
- similarity = extract_similarity options[:similarity]
59
+ # TODO I do a lot of helper method calls here. Refactor?
60
+ #
61
+ def configure_indexes_from options
62
+ index_name = @index.name
63
+
64
+ weights = Generators::Weights.from options[:weight], index_name, name
65
+ partial = Generators::Partial.from options[:partial], index_name, name
66
+ similarity = Generators::Similarity.from options[:similarity], index_name, name
59
67
 
60
68
  no_partial = Generators::Partial::None.new
61
69
  no_similarity = Generators::Similarity::None.new
@@ -99,12 +107,6 @@ module Picky
99
107
  partial.reset_backend
100
108
  end
101
109
 
102
- # Index name.
103
- #
104
- def index_name
105
- @index.name
106
- end
107
-
108
110
  # Returns the qualifiers if set or
109
111
  # just the name if not.
110
112
  #
@@ -136,11 +138,12 @@ module Picky
136
138
  @prepared_index_file ||= Backends::Prepared::Text.new prepared_index_path
137
139
  @prepared_index_file.open &block
138
140
  end
139
-
140
- # The index directory for this category.
141
- #
141
+
142
142
  def index_directory
143
- @index_directory ||= ::File.join(PICKY_ROOT, 'index', PICKY_ENVIRONMENT, @index.name.to_s)
143
+ @index.directory
144
+ end
145
+ def index_name
146
+ @index.name
144
147
  end
145
148
 
146
149
  # Identifier for technical output.
@@ -9,20 +9,6 @@ module Picky
9
9
  attr_reader :exact,
10
10
  :partial
11
11
 
12
- # Prepares and caches this category.
13
- #
14
- # This one should be used by users.
15
- #
16
- def index scheduler = Scheduler.new
17
- timed_indexing scheduler do
18
- prepare scheduler
19
- scheduler.finish
20
-
21
- cache scheduler
22
- scheduler.finish
23
- end
24
- end
25
-
26
12
  # Indexes, creates the "prepared_..." file.
27
13
  #
28
14
  def prepare scheduler = Scheduler.new
@@ -73,14 +59,6 @@ module Picky
73
59
  prepared.retrieve { |id, token| add_tokenized_token id, token, :<< }
74
60
  end
75
61
 
76
- # Return an appropriate source.
77
- #
78
- # If we have no explicit source, we'll check the index for one.
79
- #
80
- def source
81
- (@source = extract_source(@source, nil_ok: true)) || @index.source
82
- end
83
-
84
62
  # Return the key format.
85
63
  #
86
64
  # If no key_format is defined on the category
@@ -98,6 +76,14 @@ module Picky
98
76
  def from
99
77
  @from || name
100
78
  end
79
+
80
+ # Return an appropriate source.
81
+ #
82
+ # If we have no explicit source, we'll check the index for one.
83
+ #
84
+ def source
85
+ @source || @index.source
86
+ end
101
87
 
102
88
  # The indexer is lazily generated and cached.
103
89
  #
@@ -4,7 +4,6 @@
4
4
  # Use rack's environment for the search engine.
5
5
  #
6
6
  ENV['PICKY_ENV'] ||= ENV['RUBY_ENV'] || ENV['RACK_ENV']
7
-
8
7
  PICKY_ENVIRONMENT = ENV['PICKY_ENV'] || 'development' unless defined? PICKY_ENVIRONMENT
9
8
  PICKY_ROOT = Dir.pwd unless defined? PICKY_ROOT
10
9
 
@@ -1,3 +1,5 @@
1
+ # Removes and reinstalls convenience generator accessors.
2
+ #
1
3
  module Picky
2
4
  remove_const :Partial if defined? Partial
3
5
  Partial = Generators::Partial