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,23 @@
1
+ module Adapters
2
+ # Adapter that is plugged into a Rack outlet.
3
+ #
4
+ module Rack
5
+
6
+ # Subclasses of this class should respond to
7
+ # * to_app(options)
8
+ #
9
+ class Base
10
+
11
+ # Puts together an appropriately structured Rack response.
12
+ #
13
+ # Note: Bytesize is needed to have special characters not trip up Rack.
14
+ #
15
+ def respond_with response, content_type = 'application/json'
16
+ [200, { 'Content-Type' => content_type, 'Content-Length' => response.bytesize.to_s }, [response]]
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,33 @@
1
+ module Adapters
2
+
3
+ #
4
+ #
5
+ module Rack
6
+
7
+ class LiveParameters < Base
8
+
9
+ def initialize live_parameters
10
+ @live_parameters = live_parameters
11
+ end
12
+
13
+ #
14
+ #
15
+ def to_app options = {}
16
+ # For capturing by the lambda block.
17
+ #
18
+ live_parameters = @live_parameters
19
+
20
+ lambda do |env|
21
+ params = ::Rack::Request.new(env).params
22
+
23
+ results = live_parameters.parameters params
24
+
25
+ respond_with results.to_json
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,65 @@
1
+ module Adapters
2
+ # This is an adapter that is plugged into a Rack outlet.
3
+ #
4
+ # It looks at what is given to it and generate an appropriate
5
+ # adapter for it.
6
+ #
7
+ # For example, if you give it a query, it will extract the query param etc.
8
+ # and call search_with_text on it if it is called by Rack.
9
+ #
10
+ module Rack
11
+
12
+ # TODO Rename to Search.
13
+ #
14
+ class Query < Base
15
+
16
+ @@defaults = {
17
+ query_key: 'query'.freeze,
18
+ ids_key: 'ids'.freeze,
19
+ offset_key: 'offset'.freeze,
20
+ content_type: 'application/json'.freeze
21
+ }
22
+
23
+ def initialize query
24
+ @query = query
25
+ @defaults = @@defaults.dup
26
+ end
27
+
28
+ def to_app options = {}
29
+ # For capturing in the lambda.
30
+ #
31
+ query = @query
32
+ query_key = options[:query_key] || @defaults[:query_key]
33
+ content_type = options[:content_type] || @defaults[:content_type]
34
+
35
+ lambda do |env|
36
+ params = ::Rack::Request.new(env).params
37
+
38
+ results = query.search_with_text *extracted(params)
39
+
40
+ PickyLog.log results.to_log(params[query_key])
41
+
42
+ respond_with results.to_response, content_type
43
+ end
44
+ end
45
+
46
+ # Helper method to extract the params
47
+ #
48
+ # Defaults are 20 ids, offset 0.
49
+ #
50
+ UTF8_STRING = 'UTF-8'.freeze
51
+ def extracted params
52
+ [
53
+ # query is encoded in ASCII
54
+ #
55
+ params[@defaults[:query_key]] && params[@defaults[:query_key]].force_encoding(UTF8_STRING),
56
+ params[@defaults[:ids_key]] && params[@defaults[:ids_key]].to_i || 20,
57
+ params[@defaults[:offset_key]] && params[@defaults[:offset_key]].to_i || 0
58
+ ]
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,30 @@
1
+ module Adapters
2
+
3
+ # This is an adapter that is plugged into a Rack outlet.
4
+ #
5
+ # It looks at what is given to it and generate an appropriate
6
+ # adapter for it.
7
+ #
8
+ # For example, if you give it a query, it will extract the query param etc.
9
+ # and call search_with_text on it if it is called by Rack.
10
+ #
11
+ # Usage:
12
+ # Adapters::Rack.app_for(thing, options)
13
+ #
14
+ module Rack
15
+
16
+ # Generates the appropriate app for Rack.
17
+ #
18
+ @@mapping = {
19
+ :search_with_text => Query,
20
+ :parameters => LiveParameters
21
+ }
22
+ def self.app_for thing, options = {}
23
+ @@mapping.each_pair do |method, adapter|
24
+ return adapter.new(thing).to_app(options) if thing.respond_to?(method)
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -161,7 +161,7 @@ class Application
161
161
  # is used for indexing by default.
162
162
  #
163
163
  def indexing options = {}
164
- Internals::Tokenizers::Index.default = Internals::Tokenizers::Index.new(options)
164
+ Tokenizers::Index.default = Tokenizers::Index.new(options)
165
165
  end
166
166
  alias default_indexing indexing
167
167
 
@@ -169,7 +169,7 @@ class Application
169
169
  # is used for querying by default.
170
170
  #
171
171
  def searching options = {}
172
- Internals::Tokenizers::Query.default = Internals::Tokenizers::Query.new(options)
172
+ Tokenizers::Query.default = Tokenizers::Query.new(options)
173
173
  end
174
174
  alias default_querying searching
175
175
  alias querying searching
@@ -190,7 +190,7 @@ class Application
190
190
  rack_adapter.call env
191
191
  end
192
192
  def rack_adapter # :nodoc:
193
- @rack_adapter ||= Internals::FrontendAdapters::Rack.new
193
+ @rack_adapter ||= FrontendAdapters::Rack.new
194
194
  end
195
195
 
196
196
  # Finalize the subclass as soon as it
@@ -236,10 +236,10 @@ APPLICATION
236
236
  def to_stats
237
237
  <<-APP
238
238
  \033[1mIndexing (default)\033[m:
239
- #{Internals::Tokenizers::Index.default.indented_to_s}
239
+ #{Tokenizers::Index.default.indented_to_s}
240
240
 
241
241
  \033[1mQuerying (default)\033[m:
242
- #{Internals::Tokenizers::Query.default.indented_to_s}
242
+ #{Tokenizers::Query.default.indented_to_s}
243
243
 
244
244
  \033[1mIndexes\033[m:
245
245
  #{Indexes.to_s.indented_to_s}
@@ -0,0 +1,108 @@
1
+ module Backend
2
+
3
+ class Backend
4
+
5
+ attr_reader :bundle_name
6
+ attr_reader :prepared, :index, :weights, :similarity, :configuration
7
+
8
+ delegate :index_name, :category_name, :to => :@category
9
+
10
+ def initialize bundle_name, category
11
+ @bundle_name = bundle_name
12
+ @category = category
13
+ @prepared = File::Text.new category.prepared_index_path
14
+ end
15
+
16
+ # Delegators.
17
+ #
18
+
19
+ # Retrieving data.
20
+ #
21
+ def retrieve &block
22
+ prepared.retrieve &block
23
+ end
24
+
25
+ # Dumping.
26
+ #
27
+ def dump_index index_hash
28
+ index.dump index_hash
29
+ end
30
+ def dump_weights weights_hash
31
+ weights.dump weights_hash
32
+ end
33
+ def dump_similarity similarity_hash
34
+ similarity.dump similarity_hash
35
+ end
36
+ def dump_configuration configuration_hash
37
+ configuration.dump configuration_hash
38
+ end
39
+
40
+ # Loading.
41
+ #
42
+ def load_index
43
+ index.load
44
+ end
45
+ def load_similarity
46
+ similarity.load
47
+ end
48
+ def load_weights
49
+ weights.load
50
+ end
51
+ def load_configuration
52
+ configuration.load
53
+ end
54
+
55
+ # Cache ok?
56
+ #
57
+ def index_cache_ok?
58
+ index.cache_ok?
59
+ end
60
+ def similarity_cache_ok?
61
+ similarity.cache_ok?
62
+ end
63
+ def weights_cache_ok?
64
+ weights.cache_ok?
65
+ end
66
+
67
+ # Cache small?
68
+ #
69
+ def index_cache_small?
70
+ index.cache_small?
71
+ end
72
+ def similarity_cache_small?
73
+ similarity.cache_small?
74
+ end
75
+ def weights_cache_small?
76
+ weights.cache_small?
77
+ end
78
+
79
+ # Copies the indexes to the "backup" directory.
80
+ #
81
+ def backup
82
+ index.backup
83
+ weights.backup
84
+ similarity.backup
85
+ configuration.backup
86
+ end
87
+
88
+ # Restores the indexes from the "backup" directory.
89
+ #
90
+ def restore
91
+ index.restore
92
+ weights.restore
93
+ similarity.restore
94
+ configuration.restore
95
+ end
96
+
97
+ # Delete all index files.
98
+ #
99
+ def delete
100
+ index.delete
101
+ weights.delete
102
+ similarity.delete
103
+ configuration.delete
104
+ end
105
+
106
+ end
107
+
108
+ end
@@ -0,0 +1,101 @@
1
+ module Backend
2
+
3
+ # Handles all aspects of index files, such as dumping/loading.
4
+ #
5
+ module File
6
+
7
+ # Base class for all index files.
8
+ #
9
+ # Provides necessary helper methods for its
10
+ # subclasses.
11
+ # Not directly useable, as it does not provide
12
+ # dump/load methods.
13
+ #
14
+ class Basic
15
+
16
+ attr_reader :cache_path
17
+
18
+ # An index cache takes a path, without file extension,
19
+ # which will be provided by the subclasses.
20
+ #
21
+ def initialize cache_path
22
+ @cache_path = "#{cache_path}.#{extension}"
23
+ end
24
+
25
+ def to_s
26
+ cache_path
27
+ end
28
+
29
+ # The default extension for index files is "index".
30
+ #
31
+ def extension
32
+ :index
33
+ end
34
+
35
+ # Will copy the index file to a location that
36
+ # is in a directory named "backup" right under
37
+ # the directory the index file is in.
38
+ #
39
+ def backup
40
+ prepare_backup backup_directory
41
+ FileUtils.cp cache_path, target, verbose: true
42
+ end
43
+ # The backup directory of this file.
44
+ # Equal to the file's dirname plus /backup
45
+ #
46
+ def backup_directory
47
+ ::File.join ::File.dirname(cache_path), 'backup'
48
+ end
49
+ # Prepares the backup directory for the file.
50
+ #
51
+ def prepare_backup target
52
+ FileUtils.mkdir target unless Dir.exists?(target)
53
+ end
54
+
55
+ # Copies the file from its backup location back
56
+ # to the original location.
57
+ #
58
+ def restore
59
+ FileUtils.cp backup_file_path_of(cache_path), cache_path, verbose: true
60
+ end
61
+ # The backup filename.
62
+ #
63
+ def backup_file_path_of path
64
+ dir, name = ::File.split path
65
+ ::File.join dir, 'backup', name
66
+ end
67
+
68
+ # Deletes the file.
69
+ #
70
+ def delete
71
+ `rm -Rf #{cache_path}`
72
+ end
73
+
74
+ # Checks.
75
+ #
76
+
77
+ # Is this cache file suspiciously small?
78
+ # (less than 8 Bytes of size)
79
+ #
80
+ def cache_small?
81
+ size_of(cache_path) < 8
82
+ end
83
+ # Is the cache ok? (existing and larger than
84
+ # zero Bytes in size)
85
+ #
86
+ # A small cache is still ok.
87
+ #
88
+ def cache_ok?
89
+ size_of(cache_path) > 0
90
+ end
91
+ # Extracts the size of the file in Bytes.
92
+ #
93
+ def size_of path
94
+ `ls -l #{path} | awk '{print $5}'`.to_i
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,34 @@
1
+ module Backend
2
+
3
+ module File
4
+
5
+ # Index files dumped in the JSON format.
6
+ #
7
+ class JSON < Basic
8
+
9
+ # Uses the extension "json".
10
+ #
11
+ def extension
12
+ :json
13
+ end
14
+ # Loads the index hash from json format.
15
+ #
16
+ def load
17
+ Yajl::Parser.parse ::File.open(cache_path, 'r'), symbolize_keys: true
18
+ end
19
+ # Dumps the index hash in json format.
20
+ #
21
+ def dump hash
22
+ hash.dump_json cache_path
23
+ end
24
+ # A json file does not provide retrieve functionality.
25
+ #
26
+ def retrieve
27
+ raise "Can't retrieve from JSON file. Use text file."
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,34 @@
1
+ module Backend
2
+
3
+ module File
4
+
5
+ # Index data in the Ruby Marshal format.
6
+ #
7
+ class Marshal < Basic
8
+
9
+ # Uses the extension "dump".
10
+ #
11
+ def extension
12
+ :dump
13
+ end
14
+ # Loads the index hash from marshal format.
15
+ #
16
+ def load
17
+ ::Marshal.load ::File.open(cache_path, 'r:binary')
18
+ end
19
+ # Dumps the index hash in marshal format.
20
+ #
21
+ def dump hash
22
+ hash.dump_marshalled cache_path
23
+ end
24
+ # A marshal file does not provide retrieve functionality.
25
+ #
26
+ def retrieve
27
+ raise "Can't retrieve from marshalled file. Use text file."
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,56 @@
1
+ module Backend
2
+
3
+ module File
4
+
5
+ # Index data dumped in the text format.
6
+ #
7
+ class Text < Basic
8
+
9
+ # Uses the extension "txt".
10
+ #
11
+ def extension
12
+ :txt
13
+ end
14
+ # Text files are used exclusively for
15
+ # prepared data files.
16
+ #
17
+ def load
18
+ raise "Can't load from text file. Use JSON or Marshal."
19
+ end
20
+ # Text files are used exclusively for
21
+ # prepared data files.
22
+ #
23
+ def dump hash
24
+ raise "Can't dump to text file. Use JSON or Marshal."
25
+ end
26
+
27
+ # Retrieves prepared index data in the form
28
+ # * id,data\n
29
+ # * id,data\n
30
+ # * id,data\n
31
+ #
32
+ # Yields an id string and a symbol token.
33
+ #
34
+ def retrieve
35
+ id = nil
36
+ token = nil
37
+ ::File.open(cache_path, 'r:binary') do |file|
38
+ file.each_line do |line|
39
+ id, token = line.split ?,, 2
40
+ yield id, (token.chomp! || token).to_sym
41
+ end
42
+ end
43
+ end
44
+
45
+ #
46
+ #
47
+ def open_for_indexing &block
48
+ ::File.open cache_path, 'w:binary', &block
49
+ end
50
+
51
+
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,30 @@
1
+ module Backend
2
+
3
+ class Files < Backend
4
+
5
+ def initialize bundle_name, category
6
+ super bundle_name, category
7
+
8
+ # Note: We marshal the similarity, as the
9
+ # Yajl json lib cannot load symbolized
10
+ # values, just keys.
11
+ #
12
+ @index = File::JSON.new category.index_path(bundle_name, :index)
13
+ @weights = File::JSON.new category.index_path(bundle_name, :weights)
14
+ @similarity = File::Marshal.new category.index_path(bundle_name, :similarity)
15
+ @configuration = File::JSON.new category.index_path(bundle_name, :configuration)
16
+ end
17
+
18
+ def to_s
19
+ <<-FILES
20
+ Files:
21
+ #{"Index: #{@index}".indented_to_s}
22
+ #{"Weights: #{@weights}".indented_to_s}
23
+ #{"Similarity: #{@similarity}".indented_to_s}
24
+ #{"Config: #{@configuration}".indented_to_s}
25
+ FILES
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,85 @@
1
+ module Backend
2
+
3
+ class Redis
4
+
5
+ # Redis Backend Accessor.
6
+ #
7
+ # Provides necessary helper methods for its
8
+ # subclasses.
9
+ # Not directly useable, as it does not provide
10
+ # dump/load methods.
11
+ #
12
+ class Basic
13
+
14
+ attr_reader :namespace, :backend
15
+
16
+ # An index cache takes a path, without file extension,
17
+ # which will be provided by the subclasses.
18
+ #
19
+ def initialize namespace
20
+ @namespace = namespace
21
+
22
+ # TODO Turn this inside out such that people can pass in
23
+ # their own Redis instance.
24
+ #
25
+ # TODO Make the :db a real option.
26
+ #
27
+ @backend = ::Redis.new :db => 15
28
+ end
29
+
30
+ # Does nothing.
31
+ #
32
+ def load
33
+ # Nothing.
34
+ end
35
+ # We do not use Redis to retrieve data.
36
+ #
37
+ def retrieve
38
+ # Nothing.
39
+ end
40
+
41
+ # Redis does not backup.
42
+ #
43
+ def backup
44
+ # Nothing.
45
+ end
46
+
47
+ # Deletes the Redis index namespace.
48
+ #
49
+ def delete
50
+ # Not implemented here.
51
+ # Note: backend.flushdb might be the way to go,
52
+ # but since we cannot delete by key pattern,
53
+ # we don't do anything.
54
+ end
55
+
56
+ # Checks.
57
+ #
58
+
59
+ # Is this cache suspiciously small?
60
+ #
61
+ def cache_small?
62
+ size < 1
63
+ end
64
+ # Is the cache ok?
65
+ #
66
+ # A small cache is still ok.
67
+ #
68
+ def cache_ok?
69
+ size > 0
70
+ end
71
+ # Extracts the size of the file in Bytes.
72
+ #
73
+ # Note: This is a very forgiving implementation.
74
+ # But as long as Redis does not implement
75
+ # DBSIZE KEYPATTERN, we are stuck with this.
76
+ #
77
+ def size
78
+ backend.dbsize
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,49 @@
1
+ module Backend
2
+
3
+ class Redis
4
+
5
+ class ListHash < Basic
6
+
7
+ # Writes the hash into Redis.
8
+ #
9
+ def dump hash
10
+ clear
11
+ hash.each_pair do |key, values|
12
+ redis_key = "#{namespace}:#{key}"
13
+ i = 0
14
+ values.each do |value|
15
+ i += 1
16
+ backend.zadd redis_key, i, value
17
+ end
18
+ end
19
+ end
20
+
21
+ # Clear the index for this list.
22
+ #
23
+ # Note: Perhaps we can use a server only command.
24
+ # This is not the optimal way to do it.
25
+ #
26
+ def clear
27
+ redis_key = "#{namespace}:*"
28
+ backend.keys(redis_key).each do |key|
29
+ backend.del key
30
+ end
31
+ end
32
+
33
+ # Get a collection.
34
+ #
35
+ def collection sym
36
+ backend.lrange "#{namespace}:#{sym}", 0, -1
37
+ end
38
+
39
+ # Get a single value.
40
+ #
41
+ def member sym
42
+ raise "Can't retrieve a single value from a Redis ListHash. Use Index::Redis::StringHash."
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end