picky 2.5.2 → 2.6.0

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 (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