picky 2.5.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. data/lib/picky/adapters/rack/base.rb +23 -0
  2. data/lib/picky/adapters/rack/live_parameters.rb +33 -0
  3. data/lib/picky/adapters/rack/query.rb +65 -0
  4. data/lib/picky/adapters/rack.rb +30 -0
  5. data/lib/picky/application.rb +5 -5
  6. data/lib/picky/backend/backend.rb +108 -0
  7. data/lib/picky/backend/file/basic.rb +101 -0
  8. data/lib/picky/backend/file/json.rb +34 -0
  9. data/lib/picky/backend/file/marshal.rb +34 -0
  10. data/lib/picky/backend/file/text.rb +56 -0
  11. data/lib/picky/backend/files.rb +30 -0
  12. data/lib/picky/backend/redis/basic.rb +85 -0
  13. data/lib/picky/backend/redis/list_hash.rb +49 -0
  14. data/lib/picky/backend/redis/string_hash.rb +40 -0
  15. data/lib/picky/backend/redis.rb +40 -0
  16. data/lib/picky/calculations/location.rb +57 -0
  17. data/lib/picky/categories.rb +62 -0
  18. data/lib/picky/categories_indexed.rb +93 -0
  19. data/lib/picky/categories_indexing.rb +12 -0
  20. data/lib/picky/category.rb +127 -0
  21. data/lib/picky/category_indexed.rb +64 -0
  22. data/lib/picky/category_indexing.rb +145 -0
  23. data/lib/picky/{internals/ext → ext}/maybe_compile.rb +0 -0
  24. data/lib/picky/{internals/ext → ext}/ruby19/extconf.rb +0 -0
  25. data/lib/picky/{internals/ext → ext}/ruby19/performant.c +0 -0
  26. data/lib/picky/{internals/extensions → extensions}/array.rb +0 -0
  27. data/lib/picky/extensions/class.rb +11 -0
  28. data/lib/picky/{internals/extensions → extensions}/hash.rb +0 -0
  29. data/lib/picky/{internals/extensions → extensions}/module.rb +0 -0
  30. data/lib/picky/{internals/extensions → extensions}/object.rb +0 -0
  31. data/lib/picky/{internals/extensions → extensions}/symbol.rb +0 -0
  32. data/lib/picky/frontend_adapters/rack.rb +146 -0
  33. data/lib/picky/generators/aliases.rb +3 -3
  34. data/lib/picky/generators/base.rb +15 -0
  35. data/lib/picky/generators/partial/default.rb +5 -0
  36. data/lib/picky/generators/partial/none.rb +31 -0
  37. data/lib/picky/generators/partial/strategy.rb +25 -0
  38. data/lib/picky/generators/partial/substring.rb +118 -0
  39. data/lib/picky/generators/partial_generator.rb +15 -0
  40. data/lib/picky/generators/similarity/default.rb +7 -0
  41. data/lib/picky/generators/similarity/double_metaphone.rb +28 -0
  42. data/lib/picky/generators/similarity/metaphone.rb +28 -0
  43. data/lib/picky/generators/similarity/none.rb +31 -0
  44. data/lib/picky/generators/similarity/phonetic.rb +65 -0
  45. data/lib/picky/generators/similarity/soundex.rb +28 -0
  46. data/lib/picky/generators/similarity/strategy.rb +9 -0
  47. data/lib/picky/generators/similarity_generator.rb +15 -0
  48. data/lib/picky/generators/strategy.rb +14 -0
  49. data/lib/picky/generators/weights/default.rb +7 -0
  50. data/lib/picky/generators/weights/logarithmic.rb +39 -0
  51. data/lib/picky/generators/weights/strategy.rb +9 -0
  52. data/lib/picky/generators/weights_generator.rb +15 -0
  53. data/lib/picky/{internals/helpers → helpers}/measuring.rb +0 -0
  54. data/lib/picky/index/base.rb +119 -104
  55. data/lib/picky/index/base_indexed.rb +27 -0
  56. data/lib/picky/index/base_indexing.rb +119 -0
  57. data/lib/picky/index/memory.rb +6 -18
  58. data/lib/picky/index/redis.rb +6 -18
  59. data/lib/picky/indexed/bundle/base.rb +110 -0
  60. data/lib/picky/indexed/bundle/memory.rb +91 -0
  61. data/lib/picky/indexed/bundle/redis.rb +45 -0
  62. data/lib/picky/indexed/wrappers/bundle/calculation.rb +35 -0
  63. data/lib/picky/indexed/wrappers/bundle/location.rb +42 -0
  64. data/lib/picky/indexed/wrappers/bundle/wrapper.rb +43 -0
  65. data/lib/picky/indexed/wrappers/category/location.rb +25 -0
  66. data/lib/picky/indexed/wrappers/exact_first.rb +55 -0
  67. data/lib/picky/{internals/indexers → indexers}/base.rb +0 -0
  68. data/lib/picky/{internals/indexers → indexers}/parallel.rb +0 -0
  69. data/lib/picky/{internals/indexers → indexers}/serial.rb +0 -0
  70. data/lib/picky/{internals/indexers → indexers}/solr.rb +0 -0
  71. data/lib/picky/indexes.rb +73 -0
  72. data/lib/picky/indexes_indexed.rb +29 -0
  73. data/lib/picky/indexes_indexing.rb +49 -0
  74. data/lib/picky/indexing/bundle/base.rb +212 -0
  75. data/lib/picky/indexing/bundle/memory.rb +25 -0
  76. data/lib/picky/indexing/bundle/redis.rb +24 -0
  77. data/lib/picky/indexing/bundle/super_base.rb +61 -0
  78. data/lib/picky/indexing/wrappers/category/location.rb +25 -0
  79. data/lib/picky/interfaces/live_parameters.rb +8 -8
  80. data/lib/picky/loader.rb +89 -95
  81. data/lib/picky/{internals/performant.rb → performant.rb} +0 -0
  82. data/lib/picky/query/allocation.rb +84 -0
  83. data/lib/picky/query/allocations.rb +114 -0
  84. data/lib/picky/query/combination.rb +76 -0
  85. data/lib/picky/query/combinations/base.rb +70 -0
  86. data/lib/picky/query/combinations/memory.rb +48 -0
  87. data/lib/picky/query/combinations/redis.rb +86 -0
  88. data/lib/picky/query/indexes.rb +195 -0
  89. data/lib/picky/query/qualifiers.rb +76 -0
  90. data/lib/picky/query/token.rb +198 -0
  91. data/lib/picky/query/tokens.rb +103 -0
  92. data/lib/picky/{internals/query → query}/weights.rb +0 -0
  93. data/lib/picky/results.rb +1 -1
  94. data/lib/picky/search.rb +6 -6
  95. data/lib/picky/{internals/solr → solr}/schema_generator.rb +0 -0
  96. data/lib/picky/sources/db.rb +7 -7
  97. data/lib/picky/sources/wrappers/location.rb +2 -2
  98. data/lib/picky/tokenizers/base.rb +224 -0
  99. data/lib/picky/tokenizers/index.rb +30 -0
  100. data/lib/picky/tokenizers/location.rb +49 -0
  101. data/lib/picky/tokenizers/query.rb +55 -0
  102. data/lib/tasks/index.rake +4 -3
  103. data/lib/tasks/try.rake +2 -2
  104. data/spec/lib/{internals/adapters → adapters}/rack/base_spec.rb +1 -1
  105. data/spec/lib/{internals/adapters → adapters}/rack/live_parameters_spec.rb +1 -1
  106. data/spec/lib/{internals/adapters → adapters}/rack/query_spec.rb +1 -1
  107. data/spec/lib/application_spec.rb +3 -3
  108. data/spec/lib/{internals/index → backend}/file/basic_spec.rb +1 -1
  109. data/spec/lib/{internals/index → backend}/file/json_spec.rb +1 -1
  110. data/spec/lib/{internals/index → backend}/file/marshal_spec.rb +1 -1
  111. data/spec/lib/{internals/index → backend}/file/text_spec.rb +1 -1
  112. data/spec/lib/{internals/index → backend}/files_spec.rb +3 -3
  113. data/spec/lib/{internals/index → backend}/redis/basic_spec.rb +1 -1
  114. data/spec/lib/{internals/index → backend}/redis/list_hash_spec.rb +1 -1
  115. data/spec/lib/{internals/index → backend}/redis/string_hash_spec.rb +1 -1
  116. data/spec/lib/{internals/index → backend}/redis_spec.rb +11 -5
  117. data/spec/lib/{internals/calculations → calculations}/location_spec.rb +1 -1
  118. data/spec/lib/{internals/indexed/categories_spec.rb → categories_indexed_spec.rb} +10 -10
  119. data/spec/lib/{internals/indexed/category_spec.rb → category_indexed_spec.rb} +12 -12
  120. data/spec/lib/{internals/indexing/category_spec.rb → category_indexing_spec.rb} +10 -10
  121. data/spec/lib/{internals/cores_spec.rb → cores_spec.rb} +0 -0
  122. data/spec/lib/{internals/extensions → extensions}/array_spec.rb +0 -0
  123. data/spec/lib/{internals/extensions → extensions}/hash_spec.rb +0 -0
  124. data/spec/lib/{internals/extensions → extensions}/module_spec.rb +0 -0
  125. data/spec/lib/{internals/extensions → extensions}/object_spec.rb +0 -0
  126. data/spec/lib/{internals/extensions → extensions}/symbol_spec.rb +0 -0
  127. data/spec/lib/{internals/frontend_adapters → frontend_adapters}/rack_spec.rb +10 -10
  128. data/spec/lib/generators/aliases_spec.rb +3 -3
  129. data/spec/lib/{internals/generators → generators}/cacher_strategy_spec.rb +1 -1
  130. data/spec/lib/{internals/generators → generators}/partial/default_spec.rb +3 -3
  131. data/spec/lib/{internals/generators → generators}/partial/none_spec.rb +2 -2
  132. data/spec/lib/{internals/generators → generators}/partial/substring_spec.rb +1 -1
  133. data/spec/lib/{internals/generators → generators}/partial_generator_spec.rb +3 -3
  134. data/spec/lib/{internals/generators → generators}/similarity/double_metaphone_spec.rb +1 -1
  135. data/spec/lib/{internals/generators → generators}/similarity/metaphone_spec.rb +1 -1
  136. data/spec/lib/{internals/generators → generators}/similarity/none_spec.rb +1 -1
  137. data/spec/lib/{internals/generators → generators}/similarity/phonetic_spec.rb +1 -1
  138. data/spec/lib/{internals/generators → generators}/similarity/soundex_spec.rb +1 -1
  139. data/spec/lib/{internals/generators → generators}/similarity_generator_spec.rb +2 -2
  140. data/spec/lib/{internals/generators → generators}/weights/logarithmic_spec.rb +1 -1
  141. data/spec/lib/{internals/generators → generators}/weights_generator_spec.rb +5 -5
  142. data/spec/lib/{internals/helpers → helpers}/measuring_spec.rb +0 -0
  143. data/spec/lib/{internals/indexed/index_spec.rb → index/base_indexed_spec.rb} +5 -5
  144. data/spec/lib/{internals/indexing/index_spec.rb → index/base_indexing_spec.rb} +6 -19
  145. data/spec/lib/index/base_spec.rb +10 -53
  146. data/spec/lib/{internals/indexed → indexed}/bundle/memory_spec.rb +5 -5
  147. data/spec/lib/{internals/indexed → indexed}/bundle/redis_spec.rb +4 -4
  148. data/spec/lib/{internals/indexed → indexed}/wrappers/bundle/calculation_spec.rb +1 -1
  149. data/spec/lib/{internals/indexed → indexed}/wrappers/bundle/wrapper_spec.rb +1 -1
  150. data/spec/lib/{internals/indexed → indexed}/wrappers/exact_first_spec.rb +7 -7
  151. data/spec/lib/{internals/indexers → indexers}/base_spec.rb +0 -0
  152. data/spec/lib/{internals/indexers → indexers}/parallel_spec.rb +0 -0
  153. data/spec/lib/{internals/indexers → indexers}/serial_spec.rb +0 -0
  154. data/spec/lib/indexes_class_spec.rb +30 -0
  155. data/spec/lib/{indexed/indexes_spec.rb → indexes_indexed_spec.rb} +1 -1
  156. data/spec/lib/{indexing/indexes_spec.rb → indexes_indexing_spec.rb} +8 -8
  157. data/spec/lib/{internals/indexing/indexes_spec.rb → indexes_spec.rb} +15 -12
  158. data/spec/lib/{internals/indexing → indexing}/bundle/memory_partial_generation_speed_spec.rb +4 -4
  159. data/spec/lib/{internals/indexing → indexing}/bundle/memory_spec.rb +3 -3
  160. data/spec/lib/{internals/indexing → indexing}/bundle/redis_spec.rb +3 -3
  161. data/spec/lib/{internals/indexing → indexing}/bundle/super_base_spec.rb +2 -2
  162. data/spec/lib/{internals/interfaces → interfaces}/live_parameters_spec.rb +0 -0
  163. data/spec/lib/query/allocation_spec.rb +1 -1
  164. data/spec/lib/query/allocations_spec.rb +1 -1
  165. data/spec/lib/query/combination_spec.rb +5 -5
  166. data/spec/lib/query/combinations/base_spec.rb +1 -1
  167. data/spec/lib/query/combinations/memory_spec.rb +1 -1
  168. data/spec/lib/query/combinations/redis_spec.rb +1 -1
  169. data/spec/lib/query/indexes_spec.rb +1 -1
  170. data/spec/lib/query/qualifiers_spec.rb +4 -4
  171. data/spec/lib/query/token_spec.rb +3 -3
  172. data/spec/lib/query/tokens_spec.rb +32 -32
  173. data/spec/lib/search_spec.rb +5 -5
  174. data/spec/lib/{internals/solr → solr}/schema_generator_spec.rb +0 -0
  175. data/spec/lib/sources/db_spec.rb +4 -8
  176. data/spec/lib/sources/wrappers/location_spec.rb +1 -1
  177. data/spec/lib/{internals/tokenizers → tokenizers}/base_spec.rb +1 -1
  178. data/spec/lib/{internals/tokenizers → tokenizers}/index_spec.rb +1 -1
  179. data/spec/lib/{internals/tokenizers → tokenizers}/query_spec.rb +1 -1
  180. metadata +214 -215
  181. data/lib/picky/aliases.rb +0 -4
  182. data/lib/picky/index_bundle.rb +0 -48
  183. data/lib/picky/indexed/indexes.rb +0 -59
  184. data/lib/picky/indexing/indexes.rb +0 -87
  185. data/lib/picky/internals/adapters/rack/base.rb +0 -27
  186. data/lib/picky/internals/adapters/rack/live_parameters.rb +0 -37
  187. data/lib/picky/internals/adapters/rack/query.rb +0 -69
  188. data/lib/picky/internals/adapters/rack.rb +0 -34
  189. data/lib/picky/internals/calculations/location.rb +0 -59
  190. data/lib/picky/internals/frontend_adapters/rack.rb +0 -150
  191. data/lib/picky/internals/generators/base.rb +0 -19
  192. data/lib/picky/internals/generators/partial/default.rb +0 -7
  193. data/lib/picky/internals/generators/partial/none.rb +0 -35
  194. data/lib/picky/internals/generators/partial/strategy.rb +0 -29
  195. data/lib/picky/internals/generators/partial/substring.rb +0 -122
  196. data/lib/picky/internals/generators/partial_generator.rb +0 -19
  197. data/lib/picky/internals/generators/similarity/default.rb +0 -9
  198. data/lib/picky/internals/generators/similarity/double_metaphone.rb +0 -32
  199. data/lib/picky/internals/generators/similarity/metaphone.rb +0 -32
  200. data/lib/picky/internals/generators/similarity/none.rb +0 -35
  201. data/lib/picky/internals/generators/similarity/phonetic.rb +0 -69
  202. data/lib/picky/internals/generators/similarity/soundex.rb +0 -32
  203. data/lib/picky/internals/generators/similarity/strategy.rb +0 -11
  204. data/lib/picky/internals/generators/similarity_generator.rb +0 -19
  205. data/lib/picky/internals/generators/strategy.rb +0 -18
  206. data/lib/picky/internals/generators/weights/default.rb +0 -9
  207. data/lib/picky/internals/generators/weights/logarithmic.rb +0 -43
  208. data/lib/picky/internals/generators/weights/strategy.rb +0 -11
  209. data/lib/picky/internals/generators/weights_generator.rb +0 -19
  210. data/lib/picky/internals/index/backend.rb +0 -112
  211. data/lib/picky/internals/index/file/basic.rb +0 -105
  212. data/lib/picky/internals/index/file/json.rb +0 -38
  213. data/lib/picky/internals/index/file/marshal.rb +0 -38
  214. data/lib/picky/internals/index/file/text.rb +0 -60
  215. data/lib/picky/internals/index/files.rb +0 -34
  216. data/lib/picky/internals/index/redis/basic.rb +0 -89
  217. data/lib/picky/internals/index/redis/list_hash.rb +0 -53
  218. data/lib/picky/internals/index/redis/string_hash.rb +0 -44
  219. data/lib/picky/internals/index/redis.rb +0 -44
  220. data/lib/picky/internals/indexed/bundle/base.rb +0 -114
  221. data/lib/picky/internals/indexed/bundle/memory.rb +0 -95
  222. data/lib/picky/internals/indexed/bundle/redis.rb +0 -49
  223. data/lib/picky/internals/indexed/categories.rb +0 -140
  224. data/lib/picky/internals/indexed/category.rb +0 -111
  225. data/lib/picky/internals/indexed/index.rb +0 -63
  226. data/lib/picky/internals/indexed/wrappers/bundle/calculation.rb +0 -37
  227. data/lib/picky/internals/indexed/wrappers/bundle/location.rb +0 -44
  228. data/lib/picky/internals/indexed/wrappers/bundle/wrapper.rb +0 -45
  229. data/lib/picky/internals/indexed/wrappers/category/location.rb +0 -27
  230. data/lib/picky/internals/indexed/wrappers/exact_first.rb +0 -59
  231. data/lib/picky/internals/indexing/bundle/base.rb +0 -216
  232. data/lib/picky/internals/indexing/bundle/memory.rb +0 -29
  233. data/lib/picky/internals/indexing/bundle/redis.rb +0 -28
  234. data/lib/picky/internals/indexing/bundle/super_base.rb +0 -65
  235. data/lib/picky/internals/indexing/category.rb +0 -153
  236. data/lib/picky/internals/indexing/index.rb +0 -142
  237. data/lib/picky/internals/indexing/wrappers/category/location.rb +0 -27
  238. data/lib/picky/internals/query/allocation.rb +0 -88
  239. data/lib/picky/internals/query/allocations.rb +0 -118
  240. data/lib/picky/internals/query/combination.rb +0 -80
  241. data/lib/picky/internals/query/combinations/base.rb +0 -74
  242. data/lib/picky/internals/query/combinations/memory.rb +0 -52
  243. data/lib/picky/internals/query/combinations/redis.rb +0 -90
  244. data/lib/picky/internals/query/indexes.rb +0 -199
  245. data/lib/picky/internals/query/qualifiers.rb +0 -82
  246. data/lib/picky/internals/query/token.rb +0 -202
  247. data/lib/picky/internals/query/tokens.rb +0 -109
  248. data/lib/picky/internals/shared/category.rb +0 -52
  249. data/lib/picky/internals/tokenizers/base.rb +0 -228
  250. data/lib/picky/internals/tokenizers/index.rb +0 -34
  251. data/lib/picky/internals/tokenizers/location.rb +0 -54
  252. data/lib/picky/internals/tokenizers/query.rb +0 -59
  253. data/lib/picky/internals.rb +0 -2
  254. data/spec/lib/aliases_spec.rb +0 -9
  255. data/spec/lib/index_bundle_spec.rb +0 -69
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ #
3
+ module Indexed # :nodoc:all
4
+
5
+ #
6
+ #
7
+ module Bundle
8
+
9
+ # This is the _actual_ index (based on Redis).
10
+ #
11
+ # Handles exact/partial index, weights index, and similarity index.
12
+ #
13
+ class Redis < Base
14
+
15
+ def initialize name, category, *args
16
+ super name, category, *args
17
+
18
+ @backend = Backend::Redis.new name, category
19
+ end
20
+
21
+ # Get the ids for the given symbol.
22
+ #
23
+ # Ids are an array of string values in Redis.
24
+ #
25
+ def ids sym
26
+ @backend.ids sym
27
+ end
28
+ # Get a weight for the given symbol.
29
+ #
30
+ # A weight is a string value in Redis. TODO Convert?
31
+ #
32
+ def weight sym
33
+ @backend.weight sym
34
+ end
35
+ # Settings of this bundle can be accessed via [].
36
+ #
37
+ def [] sym
38
+ @backend.setting sym
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,35 @@
1
+ module Indexed
2
+ module Wrappers
3
+
4
+ module Bundle
5
+
6
+ # A calculation rewrites the symbol into a float.
7
+ #
8
+ # TODO I really need to allow integers as keys. The code below is just not up to the needed quality.
9
+ #
10
+ class Calculation < Wrapper
11
+
12
+ #
13
+ #
14
+ def recalculate float
15
+ float
16
+ end
17
+
18
+ #
19
+ #
20
+ def ids sym
21
+ @bundle.ids recalculate(sym.to_s.to_f).to_s.to_sym
22
+ end
23
+
24
+ #
25
+ #
26
+ def weight sym
27
+ @bundle.weight recalculate(sym.to_s.to_f).to_s.to_sym
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ module Indexed
2
+ module Wrappers
3
+
4
+ module Bundle
5
+
6
+ # A location calculation recalculates a location to the Picky internal location.
7
+ #
8
+ class Location < Calculation
9
+
10
+ def initialize bundle, options = {}
11
+ super bundle
12
+
13
+ precision = options[:precision] || 1
14
+ user_grid = options[:grid] || raise("Gridsize needs to be given for location #{bundle.identifier}.")
15
+
16
+ @calculation = Calculations::Location.new user_grid, precision
17
+ end
18
+
19
+ #
20
+ #
21
+ def recalculate float
22
+ @calculation.recalculate float
23
+ end
24
+
25
+ #
26
+ #
27
+ def load
28
+ # Load first the bundle, then extract the config.
29
+ #
30
+ bundle.load
31
+ # TODO Move the to_f to the backend.
32
+ #
33
+ minimum = bundle[:location_minimum] && bundle[:location_minimum].to_f || raise("Configuration :location_minimum for #{bundle.identifier} missing. Did you run rake index already?")
34
+ @calculation.minimum = minimum
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module Indexed
2
+ module Wrappers
3
+
4
+ # Per Bundle wrappers.
5
+ #
6
+ module Bundle
7
+
8
+ # Base wrapper. Just delegates all methods to the bundle.
9
+ #
10
+ class Wrapper
11
+
12
+ attr_reader :bundle
13
+
14
+ def initialize bundle
15
+ @bundle = bundle
16
+ end
17
+
18
+ delegate :load,
19
+ :load_index,
20
+ :load_weights,
21
+ :load_similarity,
22
+ :load_configuration,
23
+ :clear_index,
24
+ :clear_weights,
25
+ :clear_similarity,
26
+ :clear_configuration,
27
+ :ids,
28
+ :weight,
29
+ :identifier,
30
+ :analyze,
31
+ :size,
32
+ :index,
33
+ :weights,
34
+ :similarity,
35
+ :configuration,
36
+ :to => :@bundle
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ module Indexed
2
+ module Wrappers
3
+ module Category
4
+
5
+ module Location
6
+
7
+ def self.install_on category, grid, precision = 1
8
+ wrapped_exact = Indexed::Wrappers::Bundle::Location.new category.indexed_exact, grid: grid, precision: precision
9
+
10
+ category.class_eval do
11
+ define_method :indexed_exact do
12
+ wrapped_exact
13
+ end
14
+ define_method :indexed_partial do
15
+ wrapped_exact
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ #
3
+ module Indexed
4
+
5
+ module Wrappers
6
+
7
+ # This index combines an exact and partial index.
8
+ # It serves to order the results such that exact hits are found first.
9
+ #
10
+ class ExactFirst < Indexed::Bundle::Base
11
+
12
+ delegate :similar,
13
+ :identifier,
14
+ :name,
15
+ :to => :@exact
16
+ delegate :index,
17
+ :category,
18
+ :weight,
19
+ :generate_partial_from,
20
+ :generate_caches_from_memory,
21
+ :generate_derived,
22
+ :dump,
23
+ :load,
24
+ :to => :@partial
25
+
26
+ def initialize category
27
+ @exact = category.indexed_exact
28
+ @partial = category.indexed_partial
29
+ end
30
+
31
+ def self.wrap index_or_category
32
+ if index_or_category.respond_to? :categories
33
+ wrap_each_of index_or_category.categories
34
+ index_or_category
35
+ else
36
+ new index_or_category
37
+ end
38
+ end
39
+ def self.wrap_each_of categories
40
+ categories.categories.collect! { |category| new(category) }
41
+ end
42
+
43
+ def ids text
44
+ @exact.ids(text) + @partial.ids(text)
45
+ end
46
+
47
+ def weight text
48
+ [@exact.weight(text) || 0, @partial.weight(text) || 0].max
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
File without changes
File without changes
@@ -0,0 +1,73 @@
1
+ # Holds all indexes and provides operations
2
+ # for extracting and working on them.
3
+ #
4
+ # Delegates a number of operations to the
5
+ # indexes.
6
+ #
7
+ class Indexes
8
+
9
+ attr_reader :indexes,
10
+ :index_mapping
11
+
12
+ delegate :size,
13
+ :each,
14
+ :to => :indexes
15
+
16
+ each_delegate :reindex,
17
+ :to => :indexes
18
+
19
+ def initialize
20
+ clear
21
+ end
22
+
23
+ # Return the Indexes instance.
24
+ #
25
+ def self.instance
26
+ @instance ||= new
27
+ end
28
+
29
+ instance_delegate :clear,
30
+ :register,
31
+ :reindex,
32
+ :[],
33
+ :to_s,
34
+ :size,
35
+ :each
36
+
37
+ # Clears the indexes and the mapping.
38
+ #
39
+ def clear
40
+ @indexes = []
41
+ @index_mapping = {}
42
+ end
43
+
44
+ # Registers an index with the indexes.
45
+ #
46
+ def register index
47
+ self.indexes << index
48
+ self.index_mapping[index.name] = index
49
+ end
50
+ def self.register index
51
+ self.instance.register index
52
+ end
53
+
54
+ # Extracts an index, given its identifier.
55
+ #
56
+ def [] identifier
57
+ index_name = identifier.to_sym
58
+ index_mapping[index_name] || raise_not_found(index_name)
59
+ end
60
+
61
+ # Raises a not found for the index.
62
+ #
63
+ def raise_not_found index_name
64
+ raise %Q{Index "#{index_name}" not found. Possible indexes: "#{indexes.map(&:name).join('", "')}".}
65
+ end
66
+
67
+ #
68
+ #
69
+ def to_s
70
+ indexes.indented_to_s
71
+ end
72
+
73
+ end
@@ -0,0 +1,29 @@
1
+ # Registers the indexes held at runtime, for queries.
2
+ #
3
+ class Indexes
4
+
5
+ instance_delegate :load_from_cache,
6
+ :reload,
7
+ :analyze
8
+
9
+ each_delegate :load_from_cache,
10
+ :to => :indexes
11
+
12
+ # Reloads all indexes, one after another,
13
+ # in the order they were added.
14
+ #
15
+ alias reload load_from_cache
16
+
17
+ # Load each index, and analyze it.
18
+ #
19
+ # Returns a hash with the findings.
20
+ #
21
+ def analyze
22
+ result = {}
23
+ indexes.each do |index|
24
+ index.analyze result
25
+ end
26
+ result
27
+ end
28
+
29
+ end
@@ -0,0 +1,49 @@
1
+ # Indexes indexing.
2
+ #
3
+ class Indexes
4
+
5
+ instance_delegate :take_snapshot,
6
+ :generate_caches,
7
+ :backup_caches,
8
+ :restore_caches,
9
+ :check_caches,
10
+ :clear_caches,
11
+ :create_directory_structure,
12
+ :index,
13
+ :index_for_tests
14
+
15
+ each_delegate :take_snapshot,
16
+ :generate_caches,
17
+ :backup_caches,
18
+ :restore_caches,
19
+ :check_caches,
20
+ :clear_caches,
21
+ :create_directory_structure,
22
+ :to => :indexes
23
+
24
+ # Runs the indexers in parallel (prepare + cache).
25
+ #
26
+ def index randomly = true
27
+ take_snapshot
28
+
29
+ # Run in parallel.
30
+ #
31
+ timed_exclaim "Indexing using #{Cores.max_processors} processors, in #{randomly ? 'random' : 'given'} order."
32
+
33
+ # Run indexing/caching forked.
34
+ #
35
+ Cores.forked self.indexes, { randomly: randomly }, &:index
36
+
37
+ timed_exclaim "Indexing finished."
38
+ end
39
+
40
+ # For integration testing – indexes for the tests
41
+ # without forking and shouting ;)
42
+ #
43
+ def index_for_tests
44
+ take_snapshot
45
+
46
+ indexes.each(&:index)
47
+ end
48
+
49
+ end
@@ -0,0 +1,212 @@
1
+ # encoding: utf-8
2
+ #
3
+ module Indexing # :nodoc:all
4
+
5
+ module Bundle
6
+
7
+ # This is the indexing bundle.
8
+ # It does all menial tasks that have nothing to do
9
+ # with the actual index running etc.
10
+ #
11
+ class Base < SuperBase
12
+
13
+ attr_accessor :partial_strategy, :weights_strategy
14
+
15
+ # Path is in which directory the cache is located.
16
+ #
17
+ def initialize name, category, similarity_strategy, partial_strategy, weights_strategy
18
+ super name, category, similarity_strategy
19
+
20
+ @partial_strategy = partial_strategy
21
+ @weights_strategy = weights_strategy
22
+ end
23
+
24
+ # Sets up a piece of the index for the given token.
25
+ #
26
+ def initialize_index_for token
27
+ index[token] ||= []
28
+ end
29
+
30
+ # Generation
31
+ #
32
+
33
+ # This method
34
+ # * Loads the base index from the "prepared..." file.
35
+ # * Generates derived indexes.
36
+ # * Dumps all the indexes into files.
37
+ #
38
+ def generate_caches_from_source
39
+ load_from_index_file
40
+ generate_caches_from_memory
41
+ end
42
+ # Generates derived indexes from the index and dumps.
43
+ #
44
+ # Note: assumes that there is something in the index
45
+ #
46
+ def generate_caches_from_memory
47
+ cache_from_memory_generation_message
48
+ generate_derived
49
+ end
50
+ def cache_from_memory_generation_message
51
+ timed_exclaim %Q{"#{identifier}": Caching from intermediate in-memory index.}
52
+ end
53
+
54
+ # Generates the weights and similarity from the main index.
55
+ #
56
+ def generate_derived
57
+ generate_weights
58
+ generate_similarity
59
+ end
60
+
61
+ # Load the data from the db.
62
+ #
63
+ def load_from_index_file
64
+ load_from_index_generation_message
65
+ clear
66
+ retrieve
67
+ end
68
+ def load_from_index_generation_message
69
+ timed_exclaim %Q{"#{identifier}": Loading index.}
70
+ end
71
+ # Retrieves the prepared index data into the index.
72
+ #
73
+ # This is in preparation for generating
74
+ # derived indexes (like weights, similarity)
75
+ # and later dumping the optimized index.
76
+ #
77
+ def retrieve
78
+ key_format = self[:key_format] || :to_i
79
+ files.retrieve do |id, token|
80
+ initialize_index_for token
81
+ index[token] << id.send(key_format)
82
+ end
83
+ end
84
+
85
+ # Generates a new index (writes its index) using the
86
+ # partial caching strategy of this bundle.
87
+ #
88
+ def generate_partial
89
+ generator = Generators::PartialGenerator.new self.index
90
+ self.index = generator.generate self.partial_strategy
91
+ end
92
+ # Generate a partial index from the given exact index.
93
+ #
94
+ def generate_partial_from exact_index
95
+ timed_exclaim %Q{"#{identifier}": Generating partial index for index.}
96
+ self.index = exact_index
97
+ self.generate_partial
98
+ self
99
+ end
100
+ # Generates a new similarity index (writes its index) using the
101
+ # given similarity caching strategy.
102
+ #
103
+ def generate_similarity
104
+ generator = Generators::SimilarityGenerator.new self.index
105
+ self.similarity = generator.generate self.similarity_strategy
106
+ end
107
+ # Generates a new weights index (writes its index) using the
108
+ # given weight caching strategy.
109
+ #
110
+ def generate_weights
111
+ generator = Generators::WeightsGenerator.new self.index
112
+ self.weights = generator.generate self.weights_strategy
113
+ end
114
+
115
+ # Saves the indexes in a dump file.
116
+ #
117
+ def dump
118
+ dump_index
119
+ dump_similarity
120
+ dump_weights
121
+ dump_configuration
122
+ end
123
+ # Dumps the core index.
124
+ #
125
+ def dump_index
126
+ timed_exclaim %Q{"#{identifier}": Dumping index.}
127
+ backend.dump_index index
128
+ end
129
+ # Dumps the weights index.
130
+ #
131
+ def dump_weights
132
+ timed_exclaim %Q{"#{identifier}": Dumping weights of index.}
133
+ backend.dump_weights weights
134
+ end
135
+ # Dumps the similarity index.
136
+ #
137
+ def dump_similarity
138
+ timed_exclaim %Q{"#{identifier}": Dumping similarity of index.}
139
+ backend.dump_similarity similarity
140
+ end
141
+ # Dumps the similarity index.
142
+ #
143
+ def dump_configuration
144
+ timed_exclaim %Q{"#{identifier}": Dumping configuration for index.}
145
+ backend.dump_configuration configuration
146
+ end
147
+
148
+ # Alerts the user if an index is missing.
149
+ #
150
+ def raise_unless_cache_exists
151
+ raise_unless_index_exists
152
+ raise_unless_similarity_exists
153
+ end
154
+ # Alerts the user if one of the necessary indexes
155
+ # (core, weights) is missing.
156
+ #
157
+ def raise_unless_index_exists
158
+ if partial_strategy.saved?
159
+ warn_if_index_small
160
+ raise_unless_index_ok
161
+ end
162
+ end
163
+ # Alerts the user if the similarity
164
+ # index is missing (given that it's used).
165
+ #
166
+ def raise_unless_similarity_exists
167
+ if similarity_strategy.saved?
168
+ warn_if_similarity_small
169
+ raise_unless_similarity_ok
170
+ end
171
+ end
172
+
173
+ # Outputs a warning for the given cache.
174
+ #
175
+ def warn_cache_small what
176
+ warn "Warning: #{what} cache for #{identifier} smaller than 16 bytes."
177
+ end
178
+ # Raises an appropriate error message for the given cache.
179
+ #
180
+ def raise_cache_missing what
181
+ raise "Error: The #{what} cache for #{identifier} is missing."
182
+ end
183
+
184
+ # Warns the user if the similarity index is small.
185
+ #
186
+ def warn_if_similarity_small
187
+ warn_cache_small :similarity if backend.similarity_cache_small?
188
+ end
189
+ # Alerts the user if the similarity index is not there.
190
+ #
191
+ def raise_unless_similarity_ok
192
+ raise_cache_missing :similarity unless backend.similarity_cache_ok?
193
+ end
194
+
195
+ # Warns the user if the core or weights indexes are small.
196
+ #
197
+ def warn_if_index_small
198
+ warn_cache_small :index if backend.index_cache_small?
199
+ warn_cache_small :weights if backend.weights_cache_small?
200
+ end
201
+ # Alerts the user if the core or weights indexes are not there.
202
+ #
203
+ def raise_unless_index_ok
204
+ raise_cache_missing :index unless backend.index_cache_ok?
205
+ raise_cache_missing :weights unless backend.weights_cache_ok?
206
+ end
207
+
208
+ end
209
+
210
+ end
211
+
212
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ #
3
+ module Indexing # :nodoc:all
4
+
5
+ module Bundle
6
+
7
+ # The memory version dumps its generated indexes to disk
8
+ # (mostly JSON) to load them into memory on startup.
9
+ #
10
+ class Memory < Base
11
+
12
+ # We're using files for the memory backend.
13
+ # E.g. dump writes files.
14
+ #
15
+ alias backend files
16
+
17
+ def to_s
18
+ "Memory\n#{@backend.indented_to_s}"
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ #
3
+ module Indexing # :nodoc:all
4
+
5
+ module Bundle
6
+
7
+ # The Redis version dumps its generated indexes to
8
+ # the Redis backend.
9
+ #
10
+ class Redis < Base
11
+
12
+ attr_reader :backend
13
+
14
+ def initialize name, category, *args
15
+ super name, category, *args
16
+
17
+ @backend = Backend::Redis.new name, category
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end