picky 2.7.0 → 3.0.0.pre1
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 +20 -16
- data/lib/picky/adapters/rack/live_parameters.rb +28 -24
- data/lib/picky/adapters/rack/search.rb +67 -0
- data/lib/picky/adapters/rack.rb +27 -23
- data/lib/picky/application.rb +246 -236
- data/lib/picky/backend/base.rb +115 -119
- data/lib/picky/backend/file/basic.rb +102 -98
- data/lib/picky/backend/file/json.rb +27 -23
- data/lib/picky/backend/file/marshal.rb +32 -28
- data/lib/picky/backend/file/text.rb +45 -41
- data/lib/picky/backend/files.rb +19 -15
- data/lib/picky/backend/redis/basic.rb +76 -72
- data/lib/picky/backend/redis/list_hash.rb +40 -36
- data/lib/picky/backend/redis/string_hash.rb +30 -26
- data/lib/picky/backend/redis.rb +32 -28
- data/lib/picky/bundle.rb +82 -57
- data/lib/{bundling.rb → picky/bundling.rb} +0 -0
- data/lib/picky/calculations/location.rb +51 -47
- data/lib/picky/categories.rb +60 -56
- data/lib/picky/categories_indexed.rb +73 -82
- data/lib/picky/categories_indexing.rb +12 -8
- data/lib/picky/category.rb +109 -120
- data/lib/picky/category_indexed.rb +39 -41
- data/lib/picky/category_indexing.rb +123 -125
- data/lib/picky/character_substituters/west_european.rb +32 -26
- data/lib/{constants.rb → picky/constants.rb} +0 -0
- data/lib/picky/cores.rb +96 -92
- data/lib/{deployment.rb → picky/deployment.rb} +0 -0
- data/lib/picky/frontend_adapters/rack.rb +133 -118
- data/lib/picky/generators/aliases.rb +5 -3
- data/lib/picky/generators/base.rb +11 -7
- data/lib/picky/generators/partial/default.rb +7 -3
- data/lib/picky/generators/partial/none.rb +24 -20
- data/lib/picky/generators/partial/strategy.rb +20 -16
- data/lib/picky/generators/partial/substring.rb +94 -90
- data/lib/picky/generators/partial_generator.rb +11 -7
- data/lib/picky/generators/similarity/default.rb +9 -5
- data/lib/picky/generators/similarity/double_metaphone.rb +20 -16
- data/lib/picky/generators/similarity/metaphone.rb +20 -16
- data/lib/picky/generators/similarity/none.rb +23 -19
- data/lib/picky/generators/similarity/phonetic.rb +49 -45
- data/lib/picky/generators/similarity/soundex.rb +20 -16
- data/lib/picky/generators/similarity/strategy.rb +10 -6
- data/lib/picky/generators/similarity_generator.rb +11 -7
- data/lib/picky/generators/strategy.rb +14 -10
- data/lib/picky/generators/weights/default.rb +9 -5
- data/lib/picky/generators/weights/logarithmic.rb +30 -26
- data/lib/picky/generators/weights/strategy.rb +10 -6
- data/lib/picky/generators/weights_generator.rb +11 -7
- data/lib/picky/helpers/measuring.rb +20 -16
- data/lib/picky/indexed/bundle/base.rb +39 -37
- data/lib/picky/indexed/bundle/memory.rb +68 -64
- data/lib/picky/indexed/bundle/redis.rb +73 -69
- data/lib/picky/indexed/wrappers/bundle/calculation.rb +26 -22
- data/lib/picky/indexed/wrappers/bundle/location.rb +30 -26
- data/lib/picky/indexed/wrappers/bundle/wrapper.rb +36 -32
- data/lib/picky/indexed/wrappers/category/location.rb +17 -13
- data/lib/picky/indexed/wrappers/exact_first.rb +46 -42
- data/lib/picky/indexers/base.rb +26 -22
- data/lib/picky/indexers/parallel.rb +62 -58
- data/lib/picky/indexers/serial.rb +41 -37
- data/lib/picky/indexes/index.rb +400 -0
- data/lib/picky/indexes/index_indexed.rb +24 -0
- data/lib/picky/indexes/index_indexing.rb +138 -0
- data/lib/picky/indexes/memory.rb +20 -0
- data/lib/picky/indexes/redis.rb +20 -0
- data/lib/picky/indexes.rb +68 -61
- data/lib/picky/indexes_indexed.rb +16 -12
- data/lib/picky/indexes_indexing.rb +41 -37
- data/lib/picky/indexing/bundle/base.rb +216 -205
- data/lib/picky/indexing/bundle/memory.rb +16 -11
- data/lib/picky/indexing/bundle/redis.rb +14 -12
- data/lib/picky/indexing/wrappers/category/location.rb +17 -13
- data/lib/picky/interfaces/live_parameters.rb +159 -154
- data/lib/picky/loader.rb +267 -304
- data/lib/picky/loggers/search.rb +20 -13
- data/lib/picky/no_source_specified_exception.rb +7 -3
- data/lib/picky/performant.rb +6 -2
- data/lib/picky/query/allocation.rb +71 -67
- data/lib/picky/query/allocations.rb +99 -94
- data/lib/picky/query/combination.rb +70 -66
- data/lib/picky/query/combinations/base.rb +56 -52
- data/lib/picky/query/combinations/memory.rb +36 -32
- data/lib/picky/query/combinations/redis.rb +66 -62
- data/lib/picky/query/indexes.rb +175 -160
- data/lib/picky/query/qualifier_category_mapper.rb +43 -0
- data/lib/picky/query/token.rb +165 -172
- data/lib/picky/query/tokens.rb +86 -82
- data/lib/picky/query/weights.rb +44 -48
- data/lib/picky/query.rb +5 -1
- data/lib/picky/rack/harakiri.rb +51 -47
- data/lib/picky/results.rb +81 -77
- data/lib/picky/search.rb +169 -158
- data/lib/picky/sinatra.rb +34 -0
- data/lib/picky/sources/base.rb +73 -70
- data/lib/picky/sources/couch.rb +61 -57
- data/lib/picky/sources/csv.rb +68 -64
- data/lib/picky/sources/db.rb +139 -135
- data/lib/picky/sources/delicious.rb +52 -48
- data/lib/picky/sources/mongo.rb +68 -63
- data/lib/picky/sources/wrappers/base.rb +20 -16
- data/lib/picky/sources/wrappers/location.rb +37 -33
- data/lib/picky/statistics.rb +46 -43
- data/lib/picky/tasks.rb +3 -0
- data/lib/picky/tokenizers/base.rb +192 -187
- data/lib/picky/tokenizers/index.rb +25 -21
- data/lib/picky/tokenizers/location.rb +33 -29
- data/lib/picky/tokenizers/query.rb +49 -43
- data/lib/picky.rb +21 -13
- data/lib/tasks/application.rake +1 -1
- data/lib/tasks/index.rake +3 -3
- data/lib/tasks/routes.rake +1 -1
- data/lib/tasks/server.rake +1 -1
- data/spec/lib/adapters/rack/base_spec.rb +1 -1
- data/spec/lib/adapters/rack/live_parameters_spec.rb +1 -1
- data/spec/lib/adapters/rack/query_spec.rb +1 -1
- data/spec/lib/application_spec.rb +39 -32
- data/spec/lib/backend/file/basic_spec.rb +2 -2
- data/spec/lib/backend/file/json_spec.rb +2 -2
- data/spec/lib/backend/file/marshal_spec.rb +2 -2
- data/spec/lib/backend/file/text_spec.rb +1 -1
- data/spec/lib/backend/files_spec.rb +14 -24
- data/spec/lib/backend/redis/basic_spec.rb +2 -2
- data/spec/lib/backend/redis/list_hash_spec.rb +3 -3
- data/spec/lib/backend/redis/string_hash_spec.rb +3 -3
- data/spec/lib/backend/redis_spec.rb +20 -13
- data/spec/lib/calculations/location_spec.rb +1 -1
- data/spec/lib/categories_indexed_spec.rb +16 -34
- data/spec/lib/category_indexed_spec.rb +9 -27
- data/spec/lib/category_indexing_spec.rb +2 -3
- data/spec/lib/category_spec.rb +10 -10
- data/spec/lib/character_substituters/west_european_spec.rb +6 -5
- data/spec/lib/cores_spec.rb +17 -17
- data/spec/lib/extensions/symbol_spec.rb +15 -1
- data/spec/lib/frontend_adapters/rack_spec.rb +20 -20
- data/spec/lib/generators/aliases_spec.rb +3 -3
- data/spec/lib/generators/cacher_strategy_spec.rb +1 -1
- data/spec/lib/generators/partial/default_spec.rb +3 -3
- data/spec/lib/generators/partial/none_spec.rb +2 -2
- data/spec/lib/generators/partial/substring_spec.rb +1 -1
- data/spec/lib/generators/partial_generator_spec.rb +3 -3
- data/spec/lib/generators/similarity/double_metaphone_spec.rb +1 -1
- data/spec/lib/generators/similarity/metaphone_spec.rb +1 -1
- data/spec/lib/generators/similarity/none_spec.rb +1 -1
- data/spec/lib/generators/similarity/phonetic_spec.rb +1 -1
- data/spec/lib/generators/similarity/soundex_spec.rb +1 -1
- data/spec/lib/generators/similarity_generator_spec.rb +2 -2
- data/spec/lib/generators/weights/logarithmic_spec.rb +1 -1
- data/spec/lib/generators/weights_generator_spec.rb +1 -1
- data/spec/lib/helpers/measuring_spec.rb +2 -2
- data/spec/lib/indexed/bundle/memory_spec.rb +6 -6
- data/spec/lib/indexed/bundle/redis_spec.rb +4 -4
- data/spec/lib/indexed/wrappers/bundle/calculation_spec.rb +2 -3
- data/spec/lib/indexed/wrappers/bundle/wrapper_spec.rb +2 -2
- data/spec/lib/indexed/wrappers/exact_first_spec.rb +5 -5
- data/spec/lib/indexers/base_spec.rb +1 -1
- data/spec/lib/indexers/parallel_spec.rb +1 -1
- data/spec/lib/indexers/serial_spec.rb +1 -1
- data/spec/lib/{index/base_indexed_spec.rb → indexes/index_indexed_spec.rb} +3 -3
- data/spec/lib/{index/base_indexing_spec.rb → indexes/index_indexing_spec.rb} +19 -2
- data/spec/lib/{index/base_spec.rb → indexes/index_spec.rb} +6 -25
- data/spec/lib/{index → indexes}/redis_spec.rb +1 -1
- data/spec/lib/indexes_class_spec.rb +2 -2
- data/spec/lib/indexes_indexed_spec.rb +1 -1
- data/spec/lib/indexes_indexing_spec.rb +1 -1
- data/spec/lib/indexes_spec.rb +1 -1
- data/spec/lib/indexing/bundle/base_spec.rb +7 -5
- data/spec/lib/indexing/bundle/memory_partial_generation_speed_spec.rb +4 -4
- data/spec/lib/indexing/bundle/memory_spec.rb +15 -15
- data/spec/lib/indexing/bundle/redis_spec.rb +9 -9
- data/spec/lib/interfaces/live_parameters_spec.rb +5 -5
- data/spec/lib/loader_spec.rb +17 -19
- data/spec/lib/loggers/search_spec.rb +2 -2
- 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 +4 -4
- 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 +7 -2
- data/spec/lib/query/qualifier_category_mapper_spec.rb +34 -0
- data/spec/lib/query/token_spec.rb +32 -53
- data/spec/lib/query/tokens_spec.rb +30 -35
- data/spec/lib/query/weights_spec.rb +16 -16
- data/spec/lib/rack/harakiri_spec.rb +5 -5
- data/spec/lib/results_spec.rb +1 -1
- data/spec/lib/search_spec.rb +24 -22
- data/spec/lib/sinatra_spec.rb +36 -0
- data/spec/lib/sources/base_spec.rb +1 -1
- data/spec/lib/sources/couch_spec.rb +9 -9
- data/spec/lib/sources/csv_spec.rb +7 -7
- data/spec/lib/sources/db_spec.rb +2 -2
- data/spec/lib/sources/delicious_spec.rb +5 -5
- data/spec/lib/sources/mongo_spec.rb +7 -7
- data/spec/lib/sources/wrappers/base_spec.rb +2 -2
- data/spec/lib/sources/wrappers/location_spec.rb +1 -1
- data/spec/lib/statistics_spec.rb +1 -1
- data/spec/lib/tokenizers/base_spec.rb +2 -2
- data/spec/lib/tokenizers/index_spec.rb +1 -1
- data/spec/lib/tokenizers/query_spec.rb +1 -1
- metadata +30 -30
- data/lib/picky/adapters/rack/query.rb +0 -65
- data/lib/picky/index/base.rb +0 -409
- data/lib/picky/index/base_indexed.rb +0 -29
- data/lib/picky/index/base_indexing.rb +0 -127
- data/lib/picky/index/memory.rb +0 -16
- data/lib/picky/index/redis.rb +0 -16
- data/lib/picky/query/qualifiers.rb +0 -76
- data/lib/picky/query/solr.rb +0 -60
- data/lib/picky/signals.rb +0 -8
- data/lib/picky-tasks.rb +0 -6
- data/lib/tasks/spec.rake +0 -11
- data/spec/lib/query/qualifiers_spec.rb +0 -31
|
@@ -1,144 +1,159 @@
|
|
|
1
|
-
|
|
1
|
+
module Picky
|
|
2
2
|
|
|
3
|
-
module FrontendAdapters
|
|
3
|
+
module FrontendAdapters
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
class Rack # :nodoc:all
|
|
8
|
-
|
|
9
|
-
#
|
|
5
|
+
# TODO Rename to Routing again. Push everything back into appropriate Adapters.
|
|
10
6
|
#
|
|
11
|
-
|
|
12
|
-
@routes = ::Rack::Mount::RouteSet.new
|
|
13
|
-
end
|
|
14
|
-
def routes
|
|
15
|
-
@routes || reset_routes
|
|
16
|
-
end
|
|
17
|
-
def finalize
|
|
18
|
-
routes.freeze
|
|
19
|
-
end
|
|
7
|
+
class Rack # :nodoc:all
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
routes.call env
|
|
25
|
-
end
|
|
9
|
+
def initialize
|
|
10
|
+
check_gem
|
|
11
|
+
end
|
|
26
12
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
13
|
+
# Tries to require the rest_client gem.
|
|
14
|
+
#
|
|
15
|
+
def check_gem # :nodoc:
|
|
16
|
+
require 'rack/mount'
|
|
17
|
+
rescue LoadError
|
|
18
|
+
warn_gem_missing 'rack-mount', 'the Picky routing'
|
|
19
|
+
exit 1
|
|
33
20
|
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
#
|
|
24
|
+
def reset_routes
|
|
25
|
+
@routes = ::Rack::Mount::RouteSet.new
|
|
26
|
+
end
|
|
27
|
+
def routes
|
|
28
|
+
@routes || reset_routes
|
|
29
|
+
end
|
|
30
|
+
def finalize
|
|
31
|
+
routes.freeze
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Routing simply delegates to the route set to handle a request.
|
|
35
|
+
#
|
|
36
|
+
def call env
|
|
37
|
+
routes.call env
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# API method.
|
|
41
|
+
#
|
|
42
|
+
def route options = {}
|
|
43
|
+
mappings, route_options = split options
|
|
44
|
+
mappings.each do |url, query|
|
|
45
|
+
route_one url, query, route_options
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
# Splits the route method options
|
|
49
|
+
# into real options and route options (/regexp/ => thing or 'some/path' => thing).
|
|
50
|
+
#
|
|
51
|
+
def split options
|
|
52
|
+
mappings = {}
|
|
53
|
+
route_options = {}
|
|
54
|
+
options.each_pair do |key, value|
|
|
55
|
+
if Regexp === key or String === key
|
|
56
|
+
mappings[key] = value
|
|
57
|
+
else
|
|
58
|
+
route_options[key] = value
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
[mappings, route_options]
|
|
57
62
|
end
|
|
58
|
-
def
|
|
59
|
-
|
|
63
|
+
def route_one url, query, route_options = {}
|
|
64
|
+
raise RouteTargetNilError.new(url) unless query
|
|
65
|
+
routes.add_route Adapters::Rack.app_for(query, route_options), default_options(url, route_options), {}, query.to_s
|
|
66
|
+
end
|
|
67
|
+
class RouteTargetNilError < StandardError
|
|
68
|
+
def initialize url
|
|
69
|
+
@url = url
|
|
70
|
+
end
|
|
71
|
+
def to_s
|
|
72
|
+
"Routing for #{@url.inspect} was defined with a nil target object, i.e. #{@url.inspect} => nil."
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
#
|
|
76
|
+
#
|
|
77
|
+
def root status
|
|
78
|
+
answer %r{^/$}, STATUSES[status]
|
|
79
|
+
end
|
|
80
|
+
#
|
|
81
|
+
#
|
|
82
|
+
def default status
|
|
83
|
+
answer nil, STATUSES[status]
|
|
60
84
|
end
|
|
61
|
-
end
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
def root status
|
|
65
|
-
answer %r{^/$}, STATUSES[status]
|
|
66
|
-
end
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
def default status
|
|
70
|
-
answer nil, STATUSES[status]
|
|
71
|
-
end
|
|
72
85
|
|
|
73
86
|
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
88
|
+
# TODO Can Rack handle this for me?
|
|
89
|
+
#
|
|
90
|
+
# Note: Rack-mount already handles the 404.
|
|
91
|
+
#
|
|
92
|
+
STATUSES = {
|
|
93
|
+
200 => lambda { |_| [200, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, ['']] },
|
|
94
|
+
404 => lambda { |_| [404, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, ['']] }
|
|
95
|
+
}
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
#
|
|
98
|
+
#
|
|
99
|
+
def default_options url, route_options = {}
|
|
100
|
+
url = normalized url
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
options = { request_method: 'GET' }.merge route_options
|
|
90
103
|
|
|
91
|
-
|
|
104
|
+
options[:path_info] = url if url
|
|
92
105
|
|
|
93
|
-
|
|
106
|
+
options.delete :content_type
|
|
94
107
|
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
query_params = options.delete :query
|
|
109
|
+
options[:query_string] = %r{#{generate_query_string(query_params)}} if query_params
|
|
97
110
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
options
|
|
112
|
+
end
|
|
113
|
+
#
|
|
114
|
+
#
|
|
115
|
+
def generate_query_string query_params
|
|
116
|
+
raise "At least one query string condition is needed." if query_params.size.zero?
|
|
117
|
+
raise "Too many query param conditions (only 1 allowed): #{query_params}" if query_params.size > 1
|
|
118
|
+
k, v = query_params.first
|
|
119
|
+
"#{k}=#{v}"
|
|
120
|
+
end
|
|
108
121
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
122
|
+
# Setup a route that answers using the given app.
|
|
123
|
+
#
|
|
124
|
+
def answer url = nil, app = nil
|
|
125
|
+
routes.add_route (app || STATUSES[200]), default_options(url)
|
|
126
|
+
end
|
|
114
127
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
# Returns a regular expression for the url if it is given a String-like object.
|
|
129
|
+
#
|
|
130
|
+
def normalized url
|
|
131
|
+
url.respond_to?(:to_str) ? %r{#{url}} : url
|
|
132
|
+
end
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
134
|
+
# Returns true if there are no routes defined.
|
|
135
|
+
#
|
|
136
|
+
def empty?
|
|
137
|
+
routes.length.zero?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# TODO Beautify. Rewrite!
|
|
141
|
+
#
|
|
142
|
+
def to_s
|
|
143
|
+
max_length = routes.instance_variable_get(:@routes).reduce(0) do |current_max, route|
|
|
144
|
+
route_length = route.conditions[:path_info].source.to_s.size
|
|
145
|
+
route_length > current_max ? route_length : current_max
|
|
146
|
+
end
|
|
147
|
+
"Note: Anchored (\u2713) regexps are faster, e.g. /\\A.*\\Z/ or /^.*$/.\n\n" +
|
|
148
|
+
routes.instance_variable_get(:@routes).map do |route|
|
|
149
|
+
path_info = route.conditions[:path_info]
|
|
150
|
+
anchored = ::Rack::Mount::Utils.regexp_anchored?(path_info)
|
|
151
|
+
anchored_ok = anchored ? "\u2713" : " "
|
|
152
|
+
source = path_info.source
|
|
153
|
+
"#{anchored_ok} #{source.ljust(max_length)} => #{route.name}"
|
|
154
|
+
end.join("\n")
|
|
155
|
+
end
|
|
126
156
|
|
|
127
|
-
# TODO Beautify. Rewrite!
|
|
128
|
-
#
|
|
129
|
-
def to_s
|
|
130
|
-
max_length = routes.instance_variable_get(:@routes).reduce(0) do |current_max, route|
|
|
131
|
-
route_length = route.conditions[:path_info].source.to_s.size
|
|
132
|
-
route_length > current_max ? route_length : current_max
|
|
133
|
-
end
|
|
134
|
-
"Note: Anchored (\u2713) regexps are faster, e.g. /\\A.*\\Z/ or /^.*$/.\n\n" +
|
|
135
|
-
routes.instance_variable_get(:@routes).map do |route|
|
|
136
|
-
path_info = route.conditions[:path_info]
|
|
137
|
-
anchored = ::Rack::Mount::Utils.regexp_anchored?(path_info)
|
|
138
|
-
anchored_ok = anchored ? "\u2713" : " "
|
|
139
|
-
source = path_info.source
|
|
140
|
-
"#{anchored_ok} #{source.ljust(max_length)} => #{route.name}"
|
|
141
|
-
end.join("\n")
|
|
142
157
|
end
|
|
143
158
|
|
|
144
159
|
end
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Picky
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
class Base
|
|
3
|
+
module Generators # :nodoc:all
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
# A cache generator holds an index.
|
|
6
|
+
#
|
|
7
|
+
class Base
|
|
8
|
+
|
|
9
|
+
attr_reader :inverted
|
|
10
|
+
|
|
11
|
+
def initialize inverted
|
|
12
|
+
@inverted = inverted
|
|
13
|
+
end
|
|
8
14
|
|
|
9
|
-
def initialize inverted
|
|
10
|
-
@inverted = inverted
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
end
|
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Picky
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module Generators
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
class None < Strategy
|
|
5
|
+
module Partial
|
|
8
6
|
|
|
9
|
-
#
|
|
7
|
+
# Does not generate a partial index.
|
|
10
8
|
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
class None < Strategy
|
|
10
|
+
|
|
11
|
+
# Returns an empty index.
|
|
12
|
+
#
|
|
13
|
+
def generate_from index
|
|
14
|
+
{}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Returns if this strategy's generated file is saved.
|
|
18
|
+
#
|
|
19
|
+
def saved?
|
|
20
|
+
false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Do not use the partial bundle for getting ids and weights.
|
|
24
|
+
#
|
|
25
|
+
def use_exact_for_partial?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
end
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Picky
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module Generators
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Defines whether to use the exact bundle
|
|
10
|
-
# instead of the partial one.
|
|
11
|
-
#
|
|
12
|
-
# Default is @false@.
|
|
13
|
-
#
|
|
14
|
-
# For example:
|
|
15
|
-
# Partial::None.new # Uses the exact index instead of the partial one.
|
|
5
|
+
module Partial
|
|
6
|
+
|
|
7
|
+
# Superclass for partial strategies.
|
|
16
8
|
#
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
class Strategy < Generators::Strategy
|
|
10
|
+
|
|
11
|
+
# Defines whether to use the exact bundle
|
|
12
|
+
# instead of the partial one.
|
|
13
|
+
#
|
|
14
|
+
# Default is @false@.
|
|
15
|
+
#
|
|
16
|
+
# For example:
|
|
17
|
+
# Partial::None.new # Uses the exact index instead of the partial one.
|
|
18
|
+
#
|
|
19
|
+
def use_exact_for_partial?
|
|
20
|
+
false
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
end
|
|
20
|
-
|
|
24
|
+
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
end
|
|
@@ -1,117 +1,121 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Picky
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module Generators
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
class SubstringGenerator
|
|
5
|
+
module Partial
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@from, @to = from, to
|
|
7
|
+
# Generates the right substrings for use in the substring strategy.
|
|
8
|
+
#
|
|
9
|
+
class SubstringGenerator
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
def each_subtoken token, &block
|
|
16
|
-
token.each_subtoken @from, &block
|
|
17
|
-
end
|
|
18
|
-
else
|
|
19
|
-
def each_subtoken token, &block
|
|
20
|
-
token[0..@to].intern.each_subtoken @from, &block
|
|
21
|
-
end
|
|
22
|
-
end
|
|
11
|
+
attr_reader :from, :to
|
|
23
12
|
|
|
24
|
-
|
|
13
|
+
def initialize from, to
|
|
14
|
+
@from, @to = from, to
|
|
25
15
|
|
|
26
|
-
|
|
16
|
+
if @to.zero?
|
|
17
|
+
def each_subtoken token, &block
|
|
18
|
+
token.each_subtoken @from, &block
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
def each_subtoken token, &block
|
|
22
|
+
token[0..@to].intern.each_subtoken @from, &block
|
|
23
|
+
end
|
|
24
|
+
end
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
# If given "florian"
|
|
31
|
-
# it will index "floria", "flori", "flor", "flo", "fl", "f"
|
|
32
|
-
# (Depending on what the given from value is, the example is with option from: 1)
|
|
33
|
-
#
|
|
34
|
-
class Substring < Strategy
|
|
26
|
+
end
|
|
35
27
|
|
|
36
|
-
# The from option signifies where in the symbol it
|
|
37
|
-
# will start in generating the subtokens.
|
|
38
|
-
#
|
|
39
|
-
# Examples:
|
|
40
|
-
#
|
|
41
|
-
# With :hello, and to: -1 (default)
|
|
42
|
-
# * from: 1 # => [:hello, :hell, :hel, :he, :h]
|
|
43
|
-
# * from: 4 # => [:hello, :hell]
|
|
44
|
-
#
|
|
45
|
-
# With :hello, and to: -2
|
|
46
|
-
# * from: 1 # => [:hell, :hel, :he, :h]
|
|
47
|
-
# * from: 4 # => [:hell]
|
|
48
|
-
#
|
|
49
|
-
def initialize options = {}
|
|
50
|
-
from = options[:from] || 1
|
|
51
|
-
to = options[:to] || -1
|
|
52
|
-
@generator = SubstringGenerator.new from, to
|
|
53
28
|
end
|
|
54
29
|
|
|
55
|
-
#
|
|
30
|
+
# The subtoken partial strategy.
|
|
56
31
|
#
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
# Delegator to generator#to.
|
|
32
|
+
# If given "florian"
|
|
33
|
+
# it will index "floria", "flori", "flor", "flo", "fl", "f"
|
|
34
|
+
# (Depending on what the given from value is, the example is with option from: 1)
|
|
62
35
|
#
|
|
63
|
-
|
|
64
|
-
@generator.to
|
|
65
|
-
end
|
|
36
|
+
class Substring < Strategy
|
|
66
37
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
38
|
+
# The from option signifies where in the symbol it
|
|
39
|
+
# will start in generating the subtokens.
|
|
40
|
+
#
|
|
41
|
+
# Examples:
|
|
42
|
+
#
|
|
43
|
+
# With :hello, and to: -1 (default)
|
|
44
|
+
# * from: 1 # => [:hello, :hell, :hel, :he, :h]
|
|
45
|
+
# * from: 4 # => [:hello, :hell]
|
|
46
|
+
#
|
|
47
|
+
# With :hello, and to: -2
|
|
48
|
+
# * from: 1 # => [:hell, :hel, :he, :h]
|
|
49
|
+
# * from: 4 # => [:hell]
|
|
50
|
+
#
|
|
51
|
+
def initialize options = {}
|
|
52
|
+
from = options[:from] || 1
|
|
53
|
+
to = options[:to] || -1
|
|
54
|
+
@generator = SubstringGenerator.new from, to
|
|
55
|
+
end
|
|
71
56
|
|
|
72
|
-
#
|
|
57
|
+
# Delegator to generator#from.
|
|
73
58
|
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
inverted.each_key do |token|
|
|
77
|
-
i += 1
|
|
78
|
-
if i == 5000
|
|
79
|
-
j += 1
|
|
80
|
-
timed_exclaim %Q{#{"%8i" % (i*j)} generated (current token: "#{token}").}
|
|
81
|
-
i = 0
|
|
82
|
-
end
|
|
83
|
-
generate_for token, inverted, result
|
|
59
|
+
def from
|
|
60
|
+
@generator.from
|
|
84
61
|
end
|
|
85
62
|
|
|
86
|
-
#
|
|
63
|
+
# Delegator to generator#to.
|
|
87
64
|
#
|
|
88
|
-
|
|
89
|
-
|
|
65
|
+
def to
|
|
66
|
+
@generator.to
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Generates a partial index from the given inverted index.
|
|
90
70
|
#
|
|
91
|
-
|
|
71
|
+
def generate_from inverted
|
|
72
|
+
result = {}
|
|
73
|
+
|
|
74
|
+
# Generate for each key token the subtokens.
|
|
75
|
+
#
|
|
76
|
+
i = 0
|
|
77
|
+
j = 0
|
|
78
|
+
inverted.each_key do |token|
|
|
79
|
+
i += 1
|
|
80
|
+
if i == 5000
|
|
81
|
+
j += 1
|
|
82
|
+
timed_exclaim %Q{#{"%8i" % (i*j)} generated (current token: "#{token}").}
|
|
83
|
+
i = 0
|
|
84
|
+
end
|
|
85
|
+
generate_for token, inverted, result
|
|
86
|
+
end
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
# Remove duplicate ids.
|
|
89
|
+
#
|
|
90
|
+
# THINK If it is unique for a subtoken, it is
|
|
91
|
+
# unique for all derived longer tokens.
|
|
92
|
+
#
|
|
93
|
+
result.each_value &:uniq!
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
result
|
|
96
|
+
end
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
# To each shortened token of :test
|
|
101
|
+
# :test, :tes, :te, :t
|
|
102
|
+
# add all ids of :test
|
|
103
|
+
#
|
|
104
|
+
# "token" here means just text.
|
|
105
|
+
#
|
|
106
|
+
# THINK Could be improved by appending the aforegoing ids?
|
|
107
|
+
#
|
|
108
|
+
def generate_for token, inverted, result
|
|
109
|
+
@generator.each_subtoken(token) do |subtoken|
|
|
110
|
+
if result[subtoken]
|
|
111
|
+
result[subtoken] += inverted[token] # unique
|
|
112
|
+
else
|
|
113
|
+
result[subtoken] = inverted[token].dup
|
|
114
|
+
end
|
|
112
115
|
end
|
|
113
116
|
end
|
|
114
|
-
|
|
117
|
+
|
|
118
|
+
end
|
|
115
119
|
|
|
116
120
|
end
|
|
117
121
|
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Picky
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
class PartialGenerator < Base
|
|
3
|
+
module Generators
|
|
6
4
|
|
|
7
|
-
#
|
|
5
|
+
# The partial generator uses a subtoken(downto:1) generator as default.
|
|
8
6
|
#
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
class PartialGenerator < Base
|
|
8
|
+
|
|
9
|
+
# Generate a partial index based on the given inverted index.
|
|
10
|
+
#
|
|
11
|
+
def generate strategy = Partial::Substring.new(from: 1)
|
|
12
|
+
strategy.generate_from self.inverted
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
end
|