picky 2.1.2 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/{lib → aux}/picky/cli.rb +50 -38
  2. data/bin/picky +1 -1
  3. data/lib/picky/application.rb +5 -2
  4. data/lib/picky/index/base.rb +88 -25
  5. data/lib/picky/index/memory.rb +8 -8
  6. data/lib/picky/index/redis.rb +8 -8
  7. data/lib/picky/index_bundle.rb +2 -2
  8. data/lib/picky/indexing/indexes.rb +6 -6
  9. data/lib/picky/internals/calculations/location.rb +54 -42
  10. data/lib/picky/internals/index/backend.rb +21 -21
  11. data/lib/picky/internals/index/file/text.rb +11 -11
  12. data/lib/picky/internals/index/files.rb +6 -6
  13. data/lib/picky/internals/index/redis.rb +14 -14
  14. data/lib/picky/internals/indexed/bundle/base.rb +2 -2
  15. data/lib/picky/internals/indexed/bundle/redis.rb +3 -3
  16. data/lib/picky/internals/indexed/category.rb +8 -9
  17. data/lib/picky/internals/indexed/wrappers/bundle/calculation.rb +25 -23
  18. data/lib/picky/internals/indexed/wrappers/bundle/location.rb +36 -34
  19. data/lib/picky/internals/indexed/wrappers/bundle/wrapper.rb +35 -33
  20. data/lib/picky/internals/indexed/wrappers/category/location.rb +27 -0
  21. data/lib/picky/internals/indexers/base.rb +28 -0
  22. data/lib/picky/internals/indexers/parallel.rb +64 -0
  23. data/lib/picky/internals/indexers/serial.rb +20 -29
  24. data/lib/picky/internals/indexing/bundle/base.rb +2 -2
  25. data/lib/picky/internals/indexing/bundle/super_base.rb +3 -3
  26. data/lib/picky/internals/indexing/category.rb +30 -27
  27. data/lib/picky/internals/indexing/index.rb +82 -27
  28. data/lib/picky/internals/indexing/wrappers/category/location.rb +27 -0
  29. data/lib/picky/internals/query/indexes.rb +1 -1
  30. data/lib/picky/internals/query/qualifiers.rb +7 -6
  31. data/lib/picky/internals/query/weights.rb +6 -0
  32. data/lib/picky/internals/shared/category.rb +52 -0
  33. data/lib/picky/internals/tokenizers/base.rb +1 -1
  34. data/lib/picky/internals/tokenizers/location.rb +54 -0
  35. data/lib/picky/loader.rb +16 -3
  36. data/lib/picky/no_source_specified_exception.rb +3 -0
  37. data/lib/picky/search.rb +44 -5
  38. data/lib/picky/sources/base.rb +2 -2
  39. data/lib/picky/sources/couch.rb +1 -1
  40. data/lib/picky/sources/csv.rb +1 -1
  41. data/lib/picky/sources/db.rb +9 -9
  42. data/lib/picky/sources/delicious.rb +1 -1
  43. data/lib/picky/sources/wrappers/base.rb +12 -13
  44. data/lib/picky/sources/wrappers/location.rb +24 -54
  45. data/lib/tasks/search.rake +4 -5
  46. data/lib/tasks/todo.rake +1 -1
  47. data/spec/{lib → aux/picky}/cli_spec.rb +13 -8
  48. data/spec/lib/application_spec.rb +21 -16
  49. data/spec/lib/index/base_spec.rb +74 -27
  50. data/spec/lib/index/redis_spec.rb +1 -1
  51. data/spec/lib/index_bundle_spec.rb +1 -1
  52. data/spec/lib/indexing/indexes_spec.rb +5 -5
  53. data/spec/lib/internals/calculations/location_spec.rb +14 -3
  54. data/spec/lib/internals/index/files_spec.rb +2 -3
  55. data/spec/lib/internals/index/redis_spec.rb +122 -49
  56. data/spec/lib/internals/indexed/bundle/memory_spec.rb +4 -6
  57. data/spec/lib/internals/indexed/bundle/redis_spec.rb +2 -3
  58. data/spec/lib/internals/indexed/wrappers/bundle/calculation_spec.rb +3 -3
  59. data/spec/lib/internals/indexed/wrappers/bundle/wrapper_spec.rb +3 -3
  60. data/spec/lib/internals/indexers/parallel_spec.rb +36 -0
  61. data/spec/lib/internals/indexers/serial_spec.rb +6 -14
  62. data/spec/lib/internals/indexing/bundle/memory_partial_generation_speed_spec.rb +2 -3
  63. data/spec/lib/internals/indexing/bundle/memory_spec.rb +5 -6
  64. data/spec/lib/internals/indexing/bundle/redis_spec.rb +5 -6
  65. data/spec/lib/internals/indexing/category_spec.rb +21 -6
  66. data/spec/lib/internals/indexing/index_spec.rb +43 -7
  67. data/spec/lib/query/indexes_spec.rb +1 -1
  68. data/spec/lib/search_spec.rb +51 -2
  69. data/spec/lib/sources/couch_spec.rb +6 -6
  70. data/spec/lib/sources/csv_spec.rb +4 -4
  71. data/spec/lib/sources/db_spec.rb +13 -14
  72. data/spec/lib/sources/delicious_spec.rb +3 -3
  73. data/spec/lib/sources/wrappers/base_spec.rb +9 -10
  74. data/spec/lib/sources/wrappers/location_spec.rb +11 -23
  75. metadata +14 -15
  76. data/lib/picky/auxiliary/terminal.rb +0 -219
  77. data/lib/picky/internals/configuration/index.rb +0 -67
  78. data/lib/picky/internals/indexers/no_source_specified_error.rb +0 -7
  79. data/lib/picky/internals/indexing/categories.rb +0 -46
  80. data/spec/lib/auxiliary/terminal_spec.rb +0 -150
  81. data/spec/lib/internals/configuration/index_spec.rb +0 -80
  82. data/spec/lib/internals/indexing/categories_spec.rb +0 -49
@@ -19,7 +19,7 @@ module Picky
19
19
 
20
20
  class Base
21
21
  def usage name, params
22
- puts "Usage\n picky #{name} #{params_to_s(params)}"
22
+ puts "Usage:\n picky #{name} #{params_to_s(params)}"
23
23
  end
24
24
  # String params are optional, Symbol params aren't.
25
25
  #
@@ -27,25 +27,21 @@ module Picky
27
27
  params.map { |param| param.respond_to?(:to_str) ? "[#{param}]" : param }.join(' ') if params
28
28
  end
29
29
  end
30
- class Statistics < Base
30
+ class Generate < Base
31
31
  def execute name, args, params
32
- relative_log_file = args.shift
33
- port = args.shift
34
-
35
- usage(name, params) || exit(1) unless relative_log_file
36
-
37
- ENV['PICKY_LOG_FILE'] = File.expand_path relative_log_file
38
- ENV['PICKY_STATISTICS_PORT'] = port
39
-
40
- begin
41
- require 'picky-statistics'
42
- rescue LoadError => e
43
- require 'picky/extensions/object'
44
- warn_gem_missing 'picky-statistics', 'the Picky statistics'
45
- exit 1
46
- end
32
+ Kernel.system "picky-generate #{args.join(' ')}"
33
+ end
34
+ end
35
+ class Help < Base
36
+ # Displays usage information.
37
+ #
38
+ def execute name, args, params
39
+ commands = Picky::CLI.mapping.map do |command, object_and_params|
40
+ _, *params = object_and_params
41
+ " picky #{command} #{params_to_s(params)}"
42
+ end.join(?\n)
47
43
 
48
- require 'picky-statistics/application/app'
44
+ Kernel.puts "Possible commands:\n#{commands}\n"
49
45
  end
50
46
  end
51
47
  class Live < Base
@@ -58,32 +54,47 @@ module Picky
58
54
  ENV['PICKY_LIVE_URL'] = url
59
55
  ENV['PICKY_LIVE_PORT'] = port
60
56
 
61
- begin
62
- require 'picky-live'
63
- rescue LoadError => e
64
- require 'picky/extensions/object'
65
- warn_gem_missing 'picky-live', 'the Picky Live Interface'
66
- exit 1
67
- end
68
-
57
+ require 'picky-live'
69
58
  require 'picky-live/application/app'
59
+ rescue LoadError => e
60
+ require 'picky/extensions/object'
61
+ warn_gem_missing 'picky-live', 'the Picky Live Interface'
62
+ exit 1
70
63
  end
71
64
  end
72
- class Generate < Base
65
+ class Search < Base
73
66
  def execute name, args, params
74
- Kernel.system "picky-generate #{args.join(' ')}"
67
+ url_or_path = args.shift
68
+ ids = args.shift
69
+
70
+ usage(name, params) || exit(1) unless url_or_path
71
+
72
+ require 'picky-client'
73
+ require 'picky-client/aux/terminal'
74
+ terminal = Terminal.new url_or_path, ids
75
+ terminal.run
76
+ rescue LoadError => e
77
+ require 'picky/extensions/object'
78
+ warn_gem_missing 'picky-client', 'the Picky client'
79
+ exit 1
75
80
  end
76
81
  end
77
- class Help < Base
78
- # Displays usage information.
79
- #
82
+ class Statistics < Base
80
83
  def execute name, args, params
81
- commands = Picky::CLI.mapping.map do |command, object_and_params|
82
- _, *params = object_and_params
83
- " picky #{command} #{params_to_s(params)}"
84
- end.join(?\n)
84
+ relative_log_file = args.shift
85
+ port = args.shift
85
86
 
86
- Kernel.puts "Possible commands:\n#{commands}\n"
87
+ usage(name, params) || exit(1) unless relative_log_file
88
+
89
+ ENV['PICKY_LOG_FILE'] = File.expand_path relative_log_file
90
+ ENV['PICKY_STATISTICS_PORT'] = port
91
+
92
+ require 'picky-statistics'
93
+ require 'picky-statistics/application/app'
94
+ rescue LoadError => e
95
+ require 'picky/extensions/object'
96
+ warn_gem_missing 'picky-statistics', 'the Picky statistics'
97
+ exit 1
87
98
  end
88
99
  end
89
100
 
@@ -92,8 +103,9 @@ module Picky
92
103
  @@mapping = {
93
104
  :generate => [Generate, :'{sinatra_client,unicorn_server,empty_unicorn_server}', :'app_directory_name'],
94
105
  :help => [Help],
95
- :stats => [Statistics, :'logfile (e.g. log/search.log)', 'port (default: 4567)'],
96
- :live => [Live, 'host:port/path (default: localhost:8080/admin)', 'port (default: 4568)']
106
+ :live => [Live, 'host:port/path (default: localhost:8080/admin)', 'port (default: 4568)'],
107
+ :search => [Search, :url_or_path, 'amount of ids (default 20)'],
108
+ :stats => [Statistics, :'logfile (e.g. log/search.log)', 'port (default: 4567)']
97
109
  }
98
110
  def self.mapping
99
111
  @@mapping
data/bin/picky CHANGED
@@ -5,7 +5,7 @@ begin
5
5
  require 'picky/cli'
6
6
  rescue LoadError => e
7
7
  require 'rubygems'
8
- picky_path = File.expand_path '../../lib', __FILE__
8
+ picky_path = File.expand_path '../../aux', __FILE__
9
9
  $:.unshift(picky_path) if File.directory?(picky_path) && !$:.include?(picky_path)
10
10
  require 'picky/cli'
11
11
  end
@@ -152,16 +152,19 @@ class Application
152
152
  # Returns a configured tokenizer that
153
153
  # is used for indexing by default.
154
154
  #
155
- def default_indexing options = {}
155
+ def indexing options = {}
156
156
  Internals::Tokenizers::Index.default = Internals::Tokenizers::Index.new(options)
157
157
  end
158
+ alias default_indexing indexing
158
159
 
159
160
  # Returns a configured tokenizer that
160
161
  # is used for querying by default.
161
162
  #
162
- def default_querying options = {}
163
+ def searching options = {}
163
164
  Internals::Tokenizers::Query.default = Internals::Tokenizers::Query.new(options)
164
165
  end
166
+ alias default_querying searching
167
+ alias querying searching
165
168
 
166
169
  # Routes.
167
170
  #
@@ -9,29 +9,36 @@ module Index
9
9
  #
10
10
  class Base
11
11
 
12
- attr_reader :name, :indexing, :indexed
12
+ attr_reader :name
13
13
 
14
14
  # Create a new index with a given source.
15
15
  #
16
16
  # === Parameters
17
17
  # * name: A name that will be used for the index directory and in the Picky front end.
18
- # * source: Where the data comes from, e.g. Sources::CSV.new(...)
18
+ # * source: Where the data comes from, e.g. Sources::CSV.new(...). Optional, can be defined in the block using #source.
19
19
  #
20
20
  # === Options
21
21
  # * result_identifier: Use if you'd like a different identifier/name in the results than the name of the index.
22
22
  # * after_indexing: As of this writing only used in the db source. Executes the given after_indexing as SQL after the indexing process.
23
+ # * tokenizer: The tokenizer to use for this index.
23
24
  #
24
- # Example:
25
+ # Examples:
25
26
  # my_index = Index::Memory.new(:my_index, some_source) do
26
- # define_category :bla
27
+ # category :bla
28
+ # end
29
+ #
30
+ # my_index = Index::Memory.new(:my_index) do
31
+ # source Sources::CSV.new(file: 'data/index.csv')
32
+ # category :bla
27
33
  # end
28
34
  #
29
35
  #
30
- def initialize name, source, options = {}
31
- check name, source
36
+ def initialize name, options = {}
37
+ check_name name
38
+ @name = name.to_sym
32
39
 
33
- @name = name.to_sym
34
- @indexing = Internals::Indexing::Index.new name, source, options
40
+ check_options options
41
+ @indexing = Internals::Indexing::Index.new name, options
35
42
  @indexed = Internals::Indexed::Index.new name, options
36
43
 
37
44
  # Centralized registry.
@@ -41,37 +48,97 @@ module Index
41
48
  #
42
49
  #
43
50
  instance_eval(&Proc.new) if block_given?
51
+
52
+ check_source internal_indexing.source
53
+ end
54
+ def internal_indexing
55
+ @indexing
56
+ end
57
+ def internal_indexed
58
+ @indexed
44
59
  end
45
60
  #
46
61
  # Since this is an API, we fail hard quickly.
47
62
  #
48
- def check name, source
63
+ def check_name name
49
64
  raise ArgumentError.new(<<-NAME
65
+
66
+
50
67
  The index identifier (you gave "#{name}") for Index::Memory/Index::Redis should be a String/Symbol,
51
68
  Examples:
52
69
  Index::Memory.new(:my_cool_index, ...) # Recommended
53
70
  Index::Redis.new("a-redis-index", ...)
54
71
  NAME
72
+
73
+
55
74
  ) unless name.respond_to?(:to_sym)
75
+ end
76
+ def check_options options
77
+ raise ArgumentError.new(<<-OPTIONS
78
+
79
+
80
+ Sources are not passed in as second parameter for #{self.class.name} anymore, but either
81
+ * as :source option:
82
+ #{self.class.name}.new(#{name.inspect}, source: #{options})
83
+ or
84
+ * given to the #source method inside the config block:
85
+ #{self.class.name}.new(#{name.inspect}) do
86
+ source #{options}
87
+ end
88
+
89
+ Sorry about that breaking change (in 2.2.0), didn't want to go to 3.0.0 yet!
90
+
91
+ All the best
92
+ -- Picky
93
+
94
+
95
+ OPTIONS
96
+ ) unless options.respond_to?(:[])
97
+ end
98
+ def check_source source
56
99
  raise ArgumentError.new(<<-SOURCE
57
- The index "#{name}" should use a data source that responds to the method #harvest, which yields(id, text).
100
+
101
+
102
+ The index "#{name}" should use a data source that responds to either the method #each, or the method #harvest, which yields(id, text).
58
103
  Or it could use one of the built-in sources:
59
104
  Sources::#{(Sources.constants - [:Base, :Wrappers, :NoCSVFileGiven, :NoCouchDBGiven]).join(',
60
105
  Sources::')}
106
+
107
+
61
108
  SOURCE
62
- ) unless source.respond_to?(:harvest)
109
+ ) unless source.respond_to?(:each) || source.respond_to?(:harvest)
63
110
  end
64
111
 
65
112
  def to_stats
66
113
  stats = <<-INDEX
67
114
  #{name} (#{self.class}):
68
- #{"source: #{indexing.source}".indented_to_s}
69
- #{"categories: #{indexing.categories.categories.map(&:name).join(', ')}".indented_to_s}
115
+ #{"source: #{internal_indexing.source}".indented_to_s}
116
+ #{"categories: #{internal_indexing.categories.map(&:name).join(', ')}".indented_to_s}
70
117
  INDEX
71
- stats << " result identifier: \"#{indexed.result_identifier}\"".indented_to_s unless indexed.result_identifier.to_s == indexed.name.to_s
118
+ stats << " result identifier: \"#{internal_indexed.result_identifier}\"".indented_to_s unless internal_indexed.result_identifier.to_s == internal_indexed.name.to_s
72
119
  stats
73
120
  end
74
121
 
122
+ # Define an index tokenizer on the index.
123
+ #
124
+ # Parameters are the exact same as for the default_indexing.
125
+ #
126
+ def define_indexing options = {}
127
+ internal_indexing.define_indexing options
128
+ end
129
+ alias indexing define_indexing
130
+
131
+ # Define a source on the index.
132
+ #
133
+ # Parameter is a source, either one of the standard sources or
134
+ # anything responding to #each and returning objects that
135
+ # respond to id and the category names (or the category from option).
136
+ #
137
+ def define_source source
138
+ internal_indexing.define_source source
139
+ end
140
+ alias source define_source
141
+
75
142
  # Defines a searchable category on the index.
76
143
  #
77
144
  # === Parameters
@@ -88,8 +155,8 @@ INDEX
88
155
  def define_category category_name, options = {}
89
156
  category_name = category_name.to_sym
90
157
 
91
- indexing_category = indexing.define_category category_name, options
92
- indexed_category = indexed.define_category category_name, options
158
+ indexing_category = internal_indexing.define_category category_name, options
159
+ indexed_category = internal_indexed.define_category category_name, options
93
160
 
94
161
  yield indexing_category, indexed_category if block_given?
95
162
 
@@ -157,22 +224,18 @@ INDEX
157
224
  # * ... all options of #define_category.
158
225
  #
159
226
  def define_ranged_category category_name, range, options = {}
160
- precision = options[:precision]
227
+ precision = options[:precision] || 1
161
228
 
162
229
  options = { partial: Partial::None.new }.merge options
163
230
 
164
- define_category category_name, options do |indexing, indexed|
165
- indexing.source = Sources::Wrappers::Location.new indexing, grid: range, precision: precision
166
- indexing.tokenizer = Internals::Tokenizers::Index.new
167
-
168
- exact_bundle = Indexed::Wrappers::Bundle::Location.new indexed.exact, grid: range, precision: precision
169
- indexed.exact = exact_bundle
170
- indexed.partial = exact_bundle # A partial token also uses the exact index.
231
+ define_category category_name, options do |indexing_category, indexed_category|
232
+ Internals::Indexing::Wrappers::Category::Location.install_on indexing_category, range, precision
233
+ Internals::Indexed::Wrappers::Category::Location.install_on indexed_category, range, precision
171
234
  end
172
235
  end
173
236
  alias ranged_category define_ranged_category
174
237
 
175
- # HIGHLY EXPERIMENTAL Not correctly working yet. Try it if you feel "beta".
238
+ # HIGHLY EXPERIMENTAL Not correctly working yet. Try it if you feel "beta".
176
239
  #
177
240
  # Also a range search see #define_ranged_category, but on the earth's surface.
178
241
  #
@@ -1,9 +1,9 @@
1
1
  module Index
2
-
2
+
3
3
  # An index that is persisted in files, loaded at startup and kept in memory at runtime.
4
4
  #
5
5
  class Memory < Base
6
-
6
+
7
7
  # Create a new memory index for indexing and for querying.
8
8
  #
9
9
  # Parameters:
@@ -14,15 +14,15 @@ module Index
14
14
  # * source: The source the data comes from. See Sources::Base.
15
15
  #
16
16
  # Options:
17
- # * result_identifier: Use if you'd like a different identifier/name in the results JSON than the name of the index.
17
+ # * result_identifier: Use if you'd like a different identifier/name in the results JSON than the name of the index.
18
18
  #
19
- def initialize name, source, options = {}
19
+ def initialize name, options = {}
20
+ super name, options
21
+
20
22
  options[:indexing_bundle_class] ||= Internals::Indexing::Bundle::Memory
21
23
  options[:indexed_bundle_class] ||= Internals::Indexed::Bundle::Memory
22
-
23
- super name, source, options
24
24
  end
25
-
25
+
26
26
  end
27
-
27
+
28
28
  end
@@ -1,9 +1,9 @@
1
1
  module Index
2
-
2
+
3
3
  # An index that is persisted in Redis.
4
4
  #
5
5
  class Redis < Base
6
-
6
+
7
7
  # Create a new Redis index for indexing and for querying.
8
8
  #
9
9
  # Parameters:
@@ -14,15 +14,15 @@ module Index
14
14
  # * source: The source the data comes from. See Sources::Base.
15
15
  #
16
16
  # Options:
17
- # * result_identifier: Use if you'd like a different identifier/name in the results JSON than the name of the index.
17
+ # * result_identifier: Use if you'd like a different identifier/name in the results JSON than the name of the index.
18
18
  #
19
- def initialize name, source, options = {}
19
+ def initialize name, options = {}
20
+ super name, options
21
+
20
22
  options[:indexing_bundle_class] ||= Internals::Indexing::Bundle::Redis
21
23
  options[:indexed_bundle_class] ||= Internals::Indexed::Bundle::Redis
22
-
23
- super name, source, options
24
24
  end
25
-
25
+
26
26
  end
27
-
27
+
28
28
  end
@@ -37,8 +37,8 @@ class IndexBundle # :nodoc:all
37
37
  self.indexes << index
38
38
  self.index_mapping[index.name] = index
39
39
 
40
- indexing.register index.indexing
41
- indexed.register index.indexed
40
+ indexing.register index.internal_indexing
41
+ indexed.register index.internal_indexed
42
42
  end
43
43
 
44
44
  def [] name
@@ -47,8 +47,8 @@ module Indexing # :nodoc:all
47
47
  # Run indexing/caching forked.
48
48
  #
49
49
  Cores.forked self.indexes, { randomly: randomly } do |an_index|
50
- an_index.index
51
- an_index.cache
50
+ an_index.index!
51
+ an_index.cache!
52
52
  end
53
53
 
54
54
  timed_exclaim "Indexing finished."
@@ -60,8 +60,8 @@ module Indexing # :nodoc:all
60
60
  take_snapshot
61
61
 
62
62
  self.indexes.each do |an_index|
63
- an_index.index
64
- an_index.cache
63
+ an_index.index!
64
+ an_index.cache!
65
65
  end
66
66
  end
67
67
 
@@ -69,7 +69,7 @@ module Indexing # :nodoc:all
69
69
  #
70
70
  def generate_index_only index_name, category_name = nil
71
71
  found = find index_name, category_name
72
- found.index if found
72
+ found.index! if found
73
73
  end
74
74
  # Generate only the cache for the given index:category pair.
75
75
  #
@@ -88,7 +88,7 @@ module Indexing # :nodoc:all
88
88
 
89
89
  return index unless category_name
90
90
 
91
- found = index.categories.find category_name
91
+ found = index.find category_name
92
92
  return found if found
93
93
  end
94
94
 
@@ -1,47 +1,59 @@
1
- module Calculations # :nodoc:all
2
-
3
- # A location calculation recalculates a 1-d location
4
- # to the Picky internal 1-d "grid".
5
- #
6
- # For example, if you have a location x == 12.3456,
7
- # it will be recalculated into 3, if the minimum is 9
8
- # and the gridlength is 1.
9
- #
10
- class Location
11
-
12
- attr_reader :minimum
13
-
14
- def initialize user_grid, precision = nil
15
- @user_grid = user_grid
16
- @precision = precision || 1
17
- @grid = @user_grid / (@precision + 0.5)
18
- end
19
-
20
- def minimum= minimum
21
- # Add a margin of 1 user grid.
22
- #
23
- minimum -= @user_grid
24
-
25
- # Add plus 1 grid so that the index key never falls on 0.
26
- # Why? to_i maps by default to 0.
27
- #
28
- minimum -= @grid
29
-
30
- @minimum = minimum
31
- end
32
-
1
+ module Internals
2
+ module Calculations # :nodoc:all
3
+
4
+ # A location calculation recalculates a 1-d location
5
+ # to the Picky internal 1-d "grid".
33
6
  #
7
+ # For example, if you have a location x == 12.3456,
8
+ # it will be recalculated into 3, if the minimum is 9
9
+ # and the gridlength is 1.
34
10
  #
35
- def add_margin length
36
- @minimum -= length
37
- end
38
-
39
- #
40
- #
41
- def recalculate location
42
- ((location - @minimum) / @grid).floor
11
+ class Location
12
+
13
+ attr_reader :minimum, :precision, :grid
14
+
15
+ def initialize user_grid, precision = nil
16
+ @user_grid = user_grid
17
+ @precision = precision || 1
18
+ @grid = @user_grid / (@precision + 0.5)
19
+ end
20
+
21
+ def minimum= minimum
22
+ # Add a margin of 1 user grid.
23
+ #
24
+ minimum -= @user_grid
25
+
26
+ # Add plus 1 grid so that the index key never falls on 0.
27
+ # Why? to_i maps by default to 0.
28
+ #
29
+ minimum -= @grid
30
+
31
+ @minimum = minimum
32
+ end
33
+
34
+ #
35
+ #
36
+ def add_margin length
37
+ @minimum -= length
38
+ end
39
+
40
+ #
41
+ #
42
+ def recalculated_range location
43
+ range recalculate(location)
44
+ end
45
+ #
46
+ #
47
+ def range around_location
48
+ (around_location - @precision)..(around_location + @precision)
49
+ end
50
+ #
51
+ #
52
+ def recalculate location
53
+ ((location - @minimum) / @grid).floor
54
+ end
55
+
43
56
  end
44
-
57
+
45
58
  end
46
-
47
59
  end
@@ -1,29 +1,29 @@
1
1
  module Internals
2
-
2
+
3
3
  module Index
4
-
4
+
5
5
  class Backend
6
-
6
+
7
7
  attr_reader :bundle_name
8
8
  attr_reader :prepared, :index, :weights, :similarity, :configuration
9
-
10
- delegate :index_name, :category_name, :to => :@config
11
-
12
- def initialize bundle_name, config
9
+
10
+ delegate :index_name, :category_name, :to => :@category
11
+
12
+ def initialize bundle_name, category
13
13
  @bundle_name = bundle_name
14
- @config = config
15
- @prepared = File::Text.new config.prepared_index_path
14
+ @category = category
15
+ @prepared = File::Text.new category.prepared_index_path
16
16
  end
17
-
17
+
18
18
  # Delegators.
19
19
  #
20
-
20
+
21
21
  # Retrieving data.
22
22
  #
23
23
  def retrieve &block
24
24
  prepared.retrieve &block
25
25
  end
26
-
26
+
27
27
  # Dumping.
28
28
  #
29
29
  def dump_index index_hash
@@ -38,7 +38,7 @@ module Internals
38
38
  def dump_configuration configuration_hash
39
39
  configuration.dump configuration_hash
40
40
  end
41
-
41
+
42
42
  # Loading.
43
43
  #
44
44
  def load_index
@@ -53,7 +53,7 @@ module Internals
53
53
  def load_configuration
54
54
  configuration.load
55
55
  end
56
-
56
+
57
57
  # Cache ok?
58
58
  #
59
59
  def index_cache_ok?
@@ -65,7 +65,7 @@ module Internals
65
65
  def weights_cache_ok?
66
66
  weights.cache_ok?
67
67
  end
68
-
68
+
69
69
  # Cache small?
70
70
  #
71
71
  def index_cache_small?
@@ -77,7 +77,7 @@ module Internals
77
77
  def weights_cache_small?
78
78
  weights.cache_small?
79
79
  end
80
-
80
+
81
81
  # Copies the indexes to the "backup" directory.
82
82
  #
83
83
  def backup
@@ -86,7 +86,7 @@ module Internals
86
86
  similarity.backup
87
87
  configuration.backup
88
88
  end
89
-
89
+
90
90
  # Restores the indexes from the "backup" directory.
91
91
  #
92
92
  def restore
@@ -95,7 +95,7 @@ module Internals
95
95
  similarity.restore
96
96
  configuration.restore
97
97
  end
98
-
98
+
99
99
  # Delete all index files.
100
100
  #
101
101
  def delete
@@ -104,9 +104,9 @@ module Internals
104
104
  similarity.delete
105
105
  configuration.delete
106
106
  end
107
-
107
+
108
108
  end
109
-
109
+
110
110
  end
111
-
111
+
112
112
  end