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.
- data/lib/picky/adapters/rack/base.rb +23 -0
- data/lib/picky/adapters/rack/live_parameters.rb +33 -0
- data/lib/picky/adapters/rack/query.rb +65 -0
- data/lib/picky/adapters/rack.rb +30 -0
- data/lib/picky/application.rb +5 -5
- data/lib/picky/backend/backend.rb +108 -0
- data/lib/picky/backend/file/basic.rb +101 -0
- data/lib/picky/backend/file/json.rb +34 -0
- data/lib/picky/backend/file/marshal.rb +34 -0
- data/lib/picky/backend/file/text.rb +56 -0
- data/lib/picky/backend/files.rb +30 -0
- data/lib/picky/backend/redis/basic.rb +85 -0
- data/lib/picky/backend/redis/list_hash.rb +49 -0
- data/lib/picky/backend/redis/string_hash.rb +40 -0
- data/lib/picky/backend/redis.rb +40 -0
- data/lib/picky/calculations/location.rb +57 -0
- data/lib/picky/categories.rb +62 -0
- data/lib/picky/categories_indexed.rb +93 -0
- data/lib/picky/categories_indexing.rb +12 -0
- data/lib/picky/category.rb +127 -0
- data/lib/picky/category_indexed.rb +64 -0
- data/lib/picky/category_indexing.rb +145 -0
- data/lib/picky/{internals/ext → ext}/maybe_compile.rb +0 -0
- data/lib/picky/{internals/ext → ext}/ruby19/extconf.rb +0 -0
- data/lib/picky/{internals/ext → ext}/ruby19/performant.c +0 -0
- data/lib/picky/{internals/extensions → extensions}/array.rb +0 -0
- data/lib/picky/extensions/class.rb +11 -0
- data/lib/picky/{internals/extensions → extensions}/hash.rb +0 -0
- data/lib/picky/{internals/extensions → extensions}/module.rb +0 -0
- data/lib/picky/{internals/extensions → extensions}/object.rb +0 -0
- data/lib/picky/{internals/extensions → extensions}/symbol.rb +0 -0
- data/lib/picky/frontend_adapters/rack.rb +146 -0
- data/lib/picky/generators/aliases.rb +3 -3
- data/lib/picky/generators/base.rb +15 -0
- data/lib/picky/generators/partial/default.rb +5 -0
- data/lib/picky/generators/partial/none.rb +31 -0
- data/lib/picky/generators/partial/strategy.rb +25 -0
- data/lib/picky/generators/partial/substring.rb +118 -0
- data/lib/picky/generators/partial_generator.rb +15 -0
- data/lib/picky/generators/similarity/default.rb +7 -0
- data/lib/picky/generators/similarity/double_metaphone.rb +28 -0
- data/lib/picky/generators/similarity/metaphone.rb +28 -0
- data/lib/picky/generators/similarity/none.rb +31 -0
- data/lib/picky/generators/similarity/phonetic.rb +65 -0
- data/lib/picky/generators/similarity/soundex.rb +28 -0
- data/lib/picky/generators/similarity/strategy.rb +9 -0
- data/lib/picky/generators/similarity_generator.rb +15 -0
- data/lib/picky/generators/strategy.rb +14 -0
- data/lib/picky/generators/weights/default.rb +7 -0
- data/lib/picky/generators/weights/logarithmic.rb +39 -0
- data/lib/picky/generators/weights/strategy.rb +9 -0
- data/lib/picky/generators/weights_generator.rb +15 -0
- data/lib/picky/{internals/helpers → helpers}/measuring.rb +0 -0
- data/lib/picky/index/base.rb +119 -104
- data/lib/picky/index/base_indexed.rb +27 -0
- data/lib/picky/index/base_indexing.rb +119 -0
- data/lib/picky/index/memory.rb +6 -18
- data/lib/picky/index/redis.rb +6 -18
- data/lib/picky/indexed/bundle/base.rb +110 -0
- data/lib/picky/indexed/bundle/memory.rb +91 -0
- data/lib/picky/indexed/bundle/redis.rb +45 -0
- data/lib/picky/indexed/wrappers/bundle/calculation.rb +35 -0
- data/lib/picky/indexed/wrappers/bundle/location.rb +42 -0
- data/lib/picky/indexed/wrappers/bundle/wrapper.rb +43 -0
- data/lib/picky/indexed/wrappers/category/location.rb +25 -0
- data/lib/picky/indexed/wrappers/exact_first.rb +55 -0
- data/lib/picky/{internals/indexers → indexers}/base.rb +0 -0
- data/lib/picky/{internals/indexers → indexers}/parallel.rb +0 -0
- data/lib/picky/{internals/indexers → indexers}/serial.rb +0 -0
- data/lib/picky/{internals/indexers → indexers}/solr.rb +0 -0
- data/lib/picky/indexes.rb +73 -0
- data/lib/picky/indexes_indexed.rb +29 -0
- data/lib/picky/indexes_indexing.rb +49 -0
- data/lib/picky/indexing/bundle/base.rb +212 -0
- data/lib/picky/indexing/bundle/memory.rb +25 -0
- data/lib/picky/indexing/bundle/redis.rb +24 -0
- data/lib/picky/indexing/bundle/super_base.rb +61 -0
- data/lib/picky/indexing/wrappers/category/location.rb +25 -0
- data/lib/picky/interfaces/live_parameters.rb +8 -8
- data/lib/picky/loader.rb +89 -95
- data/lib/picky/{internals/performant.rb → performant.rb} +0 -0
- data/lib/picky/query/allocation.rb +84 -0
- data/lib/picky/query/allocations.rb +114 -0
- data/lib/picky/query/combination.rb +76 -0
- data/lib/picky/query/combinations/base.rb +70 -0
- data/lib/picky/query/combinations/memory.rb +48 -0
- data/lib/picky/query/combinations/redis.rb +86 -0
- data/lib/picky/query/indexes.rb +195 -0
- data/lib/picky/query/qualifiers.rb +76 -0
- data/lib/picky/query/token.rb +198 -0
- data/lib/picky/query/tokens.rb +103 -0
- data/lib/picky/{internals/query → query}/weights.rb +0 -0
- data/lib/picky/results.rb +1 -1
- data/lib/picky/search.rb +6 -6
- data/lib/picky/{internals/solr → solr}/schema_generator.rb +0 -0
- data/lib/picky/sources/db.rb +7 -7
- data/lib/picky/sources/wrappers/location.rb +2 -2
- data/lib/picky/tokenizers/base.rb +224 -0
- data/lib/picky/tokenizers/index.rb +30 -0
- data/lib/picky/tokenizers/location.rb +49 -0
- data/lib/picky/tokenizers/query.rb +55 -0
- data/lib/tasks/index.rake +4 -3
- data/lib/tasks/try.rake +2 -2
- data/spec/lib/{internals/adapters → adapters}/rack/base_spec.rb +1 -1
- data/spec/lib/{internals/adapters → adapters}/rack/live_parameters_spec.rb +1 -1
- data/spec/lib/{internals/adapters → adapters}/rack/query_spec.rb +1 -1
- data/spec/lib/application_spec.rb +3 -3
- data/spec/lib/{internals/index → backend}/file/basic_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/file/json_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/file/marshal_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/file/text_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/files_spec.rb +3 -3
- data/spec/lib/{internals/index → backend}/redis/basic_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/redis/list_hash_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/redis/string_hash_spec.rb +1 -1
- data/spec/lib/{internals/index → backend}/redis_spec.rb +11 -5
- data/spec/lib/{internals/calculations → calculations}/location_spec.rb +1 -1
- data/spec/lib/{internals/indexed/categories_spec.rb → categories_indexed_spec.rb} +10 -10
- data/spec/lib/{internals/indexed/category_spec.rb → category_indexed_spec.rb} +12 -12
- data/spec/lib/{internals/indexing/category_spec.rb → category_indexing_spec.rb} +10 -10
- data/spec/lib/{internals/cores_spec.rb → cores_spec.rb} +0 -0
- data/spec/lib/{internals/extensions → extensions}/array_spec.rb +0 -0
- data/spec/lib/{internals/extensions → extensions}/hash_spec.rb +0 -0
- data/spec/lib/{internals/extensions → extensions}/module_spec.rb +0 -0
- data/spec/lib/{internals/extensions → extensions}/object_spec.rb +0 -0
- data/spec/lib/{internals/extensions → extensions}/symbol_spec.rb +0 -0
- data/spec/lib/{internals/frontend_adapters → frontend_adapters}/rack_spec.rb +10 -10
- data/spec/lib/generators/aliases_spec.rb +3 -3
- data/spec/lib/{internals/generators → generators}/cacher_strategy_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/partial/default_spec.rb +3 -3
- data/spec/lib/{internals/generators → generators}/partial/none_spec.rb +2 -2
- data/spec/lib/{internals/generators → generators}/partial/substring_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/partial_generator_spec.rb +3 -3
- data/spec/lib/{internals/generators → generators}/similarity/double_metaphone_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/similarity/metaphone_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/similarity/none_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/similarity/phonetic_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/similarity/soundex_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/similarity_generator_spec.rb +2 -2
- data/spec/lib/{internals/generators → generators}/weights/logarithmic_spec.rb +1 -1
- data/spec/lib/{internals/generators → generators}/weights_generator_spec.rb +5 -5
- data/spec/lib/{internals/helpers → helpers}/measuring_spec.rb +0 -0
- data/spec/lib/{internals/indexed/index_spec.rb → index/base_indexed_spec.rb} +5 -5
- data/spec/lib/{internals/indexing/index_spec.rb → index/base_indexing_spec.rb} +6 -19
- data/spec/lib/index/base_spec.rb +10 -53
- data/spec/lib/{internals/indexed → indexed}/bundle/memory_spec.rb +5 -5
- data/spec/lib/{internals/indexed → indexed}/bundle/redis_spec.rb +4 -4
- data/spec/lib/{internals/indexed → indexed}/wrappers/bundle/calculation_spec.rb +1 -1
- data/spec/lib/{internals/indexed → indexed}/wrappers/bundle/wrapper_spec.rb +1 -1
- data/spec/lib/{internals/indexed → indexed}/wrappers/exact_first_spec.rb +7 -7
- data/spec/lib/{internals/indexers → indexers}/base_spec.rb +0 -0
- data/spec/lib/{internals/indexers → indexers}/parallel_spec.rb +0 -0
- data/spec/lib/{internals/indexers → indexers}/serial_spec.rb +0 -0
- data/spec/lib/indexes_class_spec.rb +30 -0
- data/spec/lib/{indexed/indexes_spec.rb → indexes_indexed_spec.rb} +1 -1
- data/spec/lib/{indexing/indexes_spec.rb → indexes_indexing_spec.rb} +8 -8
- data/spec/lib/{internals/indexing/indexes_spec.rb → indexes_spec.rb} +15 -12
- data/spec/lib/{internals/indexing → indexing}/bundle/memory_partial_generation_speed_spec.rb +4 -4
- data/spec/lib/{internals/indexing → indexing}/bundle/memory_spec.rb +3 -3
- data/spec/lib/{internals/indexing → indexing}/bundle/redis_spec.rb +3 -3
- data/spec/lib/{internals/indexing → indexing}/bundle/super_base_spec.rb +2 -2
- data/spec/lib/{internals/interfaces → interfaces}/live_parameters_spec.rb +0 -0
- data/spec/lib/query/allocation_spec.rb +1 -1
- data/spec/lib/query/allocations_spec.rb +1 -1
- data/spec/lib/query/combination_spec.rb +5 -5
- data/spec/lib/query/combinations/base_spec.rb +1 -1
- data/spec/lib/query/combinations/memory_spec.rb +1 -1
- data/spec/lib/query/combinations/redis_spec.rb +1 -1
- data/spec/lib/query/indexes_spec.rb +1 -1
- data/spec/lib/query/qualifiers_spec.rb +4 -4
- data/spec/lib/query/token_spec.rb +3 -3
- data/spec/lib/query/tokens_spec.rb +32 -32
- data/spec/lib/search_spec.rb +5 -5
- data/spec/lib/{internals/solr → solr}/schema_generator_spec.rb +0 -0
- data/spec/lib/sources/db_spec.rb +4 -8
- data/spec/lib/sources/wrappers/location_spec.rb +1 -1
- data/spec/lib/{internals/tokenizers → tokenizers}/base_spec.rb +1 -1
- data/spec/lib/{internals/tokenizers → tokenizers}/index_spec.rb +1 -1
- data/spec/lib/{internals/tokenizers → tokenizers}/query_spec.rb +1 -1
- metadata +214 -215
- data/lib/picky/aliases.rb +0 -4
- data/lib/picky/index_bundle.rb +0 -48
- data/lib/picky/indexed/indexes.rb +0 -59
- data/lib/picky/indexing/indexes.rb +0 -87
- data/lib/picky/internals/adapters/rack/base.rb +0 -27
- data/lib/picky/internals/adapters/rack/live_parameters.rb +0 -37
- data/lib/picky/internals/adapters/rack/query.rb +0 -69
- data/lib/picky/internals/adapters/rack.rb +0 -34
- data/lib/picky/internals/calculations/location.rb +0 -59
- data/lib/picky/internals/frontend_adapters/rack.rb +0 -150
- data/lib/picky/internals/generators/base.rb +0 -19
- data/lib/picky/internals/generators/partial/default.rb +0 -7
- data/lib/picky/internals/generators/partial/none.rb +0 -35
- data/lib/picky/internals/generators/partial/strategy.rb +0 -29
- data/lib/picky/internals/generators/partial/substring.rb +0 -122
- data/lib/picky/internals/generators/partial_generator.rb +0 -19
- data/lib/picky/internals/generators/similarity/default.rb +0 -9
- data/lib/picky/internals/generators/similarity/double_metaphone.rb +0 -32
- data/lib/picky/internals/generators/similarity/metaphone.rb +0 -32
- data/lib/picky/internals/generators/similarity/none.rb +0 -35
- data/lib/picky/internals/generators/similarity/phonetic.rb +0 -69
- data/lib/picky/internals/generators/similarity/soundex.rb +0 -32
- data/lib/picky/internals/generators/similarity/strategy.rb +0 -11
- data/lib/picky/internals/generators/similarity_generator.rb +0 -19
- data/lib/picky/internals/generators/strategy.rb +0 -18
- data/lib/picky/internals/generators/weights/default.rb +0 -9
- data/lib/picky/internals/generators/weights/logarithmic.rb +0 -43
- data/lib/picky/internals/generators/weights/strategy.rb +0 -11
- data/lib/picky/internals/generators/weights_generator.rb +0 -19
- data/lib/picky/internals/index/backend.rb +0 -112
- data/lib/picky/internals/index/file/basic.rb +0 -105
- data/lib/picky/internals/index/file/json.rb +0 -38
- data/lib/picky/internals/index/file/marshal.rb +0 -38
- data/lib/picky/internals/index/file/text.rb +0 -60
- data/lib/picky/internals/index/files.rb +0 -34
- data/lib/picky/internals/index/redis/basic.rb +0 -89
- data/lib/picky/internals/index/redis/list_hash.rb +0 -53
- data/lib/picky/internals/index/redis/string_hash.rb +0 -44
- data/lib/picky/internals/index/redis.rb +0 -44
- data/lib/picky/internals/indexed/bundle/base.rb +0 -114
- data/lib/picky/internals/indexed/bundle/memory.rb +0 -95
- data/lib/picky/internals/indexed/bundle/redis.rb +0 -49
- data/lib/picky/internals/indexed/categories.rb +0 -140
- data/lib/picky/internals/indexed/category.rb +0 -111
- data/lib/picky/internals/indexed/index.rb +0 -63
- data/lib/picky/internals/indexed/wrappers/bundle/calculation.rb +0 -37
- data/lib/picky/internals/indexed/wrappers/bundle/location.rb +0 -44
- data/lib/picky/internals/indexed/wrappers/bundle/wrapper.rb +0 -45
- data/lib/picky/internals/indexed/wrappers/category/location.rb +0 -27
- data/lib/picky/internals/indexed/wrappers/exact_first.rb +0 -59
- data/lib/picky/internals/indexing/bundle/base.rb +0 -216
- data/lib/picky/internals/indexing/bundle/memory.rb +0 -29
- data/lib/picky/internals/indexing/bundle/redis.rb +0 -28
- data/lib/picky/internals/indexing/bundle/super_base.rb +0 -65
- data/lib/picky/internals/indexing/category.rb +0 -153
- data/lib/picky/internals/indexing/index.rb +0 -142
- data/lib/picky/internals/indexing/wrappers/category/location.rb +0 -27
- data/lib/picky/internals/query/allocation.rb +0 -88
- data/lib/picky/internals/query/allocations.rb +0 -118
- data/lib/picky/internals/query/combination.rb +0 -80
- data/lib/picky/internals/query/combinations/base.rb +0 -74
- data/lib/picky/internals/query/combinations/memory.rb +0 -52
- data/lib/picky/internals/query/combinations/redis.rb +0 -90
- data/lib/picky/internals/query/indexes.rb +0 -199
- data/lib/picky/internals/query/qualifiers.rb +0 -82
- data/lib/picky/internals/query/token.rb +0 -202
- data/lib/picky/internals/query/tokens.rb +0 -109
- data/lib/picky/internals/shared/category.rb +0 -52
- data/lib/picky/internals/tokenizers/base.rb +0 -228
- data/lib/picky/internals/tokenizers/index.rb +0 -34
- data/lib/picky/internals/tokenizers/location.rb +0 -54
- data/lib/picky/internals/tokenizers/query.rb +0 -59
- data/lib/picky/internals.rb +0 -2
- data/spec/lib/aliases_spec.rb +0 -9
- 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
|
data/lib/picky/application.rb
CHANGED
|
@@ -161,7 +161,7 @@ class Application
|
|
|
161
161
|
# is used for indexing by default.
|
|
162
162
|
#
|
|
163
163
|
def indexing options = {}
|
|
164
|
-
|
|
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
|
-
|
|
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 ||=
|
|
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
|
-
#{
|
|
239
|
+
#{Tokenizers::Index.default.indented_to_s}
|
|
240
240
|
|
|
241
241
|
\033[1mQuerying (default)\033[m:
|
|
242
|
-
#{
|
|
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
|