picky 2.7.0 → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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,82 +1,86 @@
|
|
1
|
-
module
|
1
|
+
module Picky
|
2
2
|
|
3
|
-
|
4
|
-
# [token, index] [other_token, other_index], ...
|
5
|
-
#
|
6
|
-
class Allocation # :nodoc:all
|
3
|
+
module Query
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
#
|
5
|
+
# An allocation has a number of combinations:
|
6
|
+
# [token, index] [other_token, other_index], ...
|
11
7
|
#
|
12
|
-
|
13
|
-
@combinations = combinations
|
14
|
-
@result_identifier = result_identifier
|
15
|
-
end
|
8
|
+
class Allocation # :nodoc:all
|
16
9
|
|
17
|
-
|
18
|
-
@combinations.hash
|
19
|
-
end
|
20
|
-
def eql? other_allocation
|
21
|
-
true # FIXME
|
22
|
-
# @combinations.eql? other_allocation.combinations
|
23
|
-
end
|
10
|
+
attr_reader :count, :ids, :score, :combinations, :result_identifier
|
24
11
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
12
|
+
#
|
13
|
+
#
|
14
|
+
def initialize combinations, result_identifier
|
15
|
+
@combinations = combinations
|
16
|
+
@result_identifier = result_identifier
|
17
|
+
end
|
30
18
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
19
|
+
def hash
|
20
|
+
@combinations.hash
|
21
|
+
end
|
22
|
+
def eql? other_allocation
|
23
|
+
true # FIXME
|
24
|
+
# @combinations.eql? other_allocation.combinations
|
25
|
+
end
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@ids = ids.slice!(offset, amount) || [] # slice out the relevant part
|
43
|
-
end
|
27
|
+
# Scores its combinations and caches the result.
|
28
|
+
#
|
29
|
+
def calculate_score weights
|
30
|
+
@score ||= @combinations.calculate_score(weights)
|
31
|
+
end
|
44
32
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#
|
51
|
-
#
|
52
|
-
def remove identifiers = [] # categories
|
53
|
-
@combinations.remove identifiers
|
54
|
-
end
|
33
|
+
# Asks the combinations for the (intersected) ids.
|
34
|
+
#
|
35
|
+
def calculate_ids amount, offset
|
36
|
+
@combinations.ids amount, offset # Calculate as many ids as are necessary.
|
37
|
+
end
|
55
38
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
39
|
+
# This starts the searching process.
|
40
|
+
#
|
41
|
+
def process! amount, offset
|
42
|
+
ids = calculate_ids amount, offset
|
43
|
+
@count = ids.size # cache the count before throwing away the ids
|
44
|
+
@ids = ids.slice!(offset, amount) || [] # slice out the relevant part
|
45
|
+
end
|
61
46
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
47
|
+
#
|
48
|
+
#
|
49
|
+
def keep identifiers = [] # categories
|
50
|
+
@combinations.keep identifiers
|
51
|
+
end
|
52
|
+
#
|
53
|
+
#
|
54
|
+
def remove identifiers = [] # categories
|
55
|
+
@combinations.remove identifiers
|
56
|
+
end
|
67
57
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
58
|
+
# Sort highest score first.
|
59
|
+
#
|
60
|
+
def <=> other_allocation
|
61
|
+
other_allocation.score <=> self.score
|
62
|
+
end
|
63
|
+
|
64
|
+
# Transform the allocation into result form.
|
65
|
+
#
|
66
|
+
def to_result
|
67
|
+
[self.result_identifier, self.score, self.count, @combinations.to_result, self.ids] if self.count > 0
|
68
|
+
end
|
69
|
+
|
70
|
+
# Json representation of this allocation.
|
71
|
+
#
|
72
|
+
# Note: Delegates to to_result.
|
73
|
+
#
|
74
|
+
def to_json
|
75
|
+
to_result.to_json
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
#
|
80
|
+
def to_s
|
81
|
+
"Allocation(#{to_result})"
|
82
|
+
end
|
75
83
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
def to_s
|
79
|
-
"Allocation(#{to_result})"
|
80
84
|
end
|
81
85
|
|
82
86
|
end
|
@@ -1,112 +1,117 @@
|
|
1
|
-
module
|
2
|
-
# Container class for allocations.
|
3
|
-
#
|
4
|
-
class Allocations # :nodoc:all
|
1
|
+
module Picky
|
5
2
|
|
6
|
-
|
7
|
-
attr_reader :total
|
3
|
+
module Query
|
8
4
|
|
9
|
-
|
10
|
-
@allocations = allocations
|
11
|
-
end
|
12
|
-
|
13
|
-
# Score each allocation.
|
5
|
+
# Container class for allocations.
|
14
6
|
#
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
class Allocations # :nodoc:all
|
8
|
+
|
9
|
+
delegate :each, :inject, :empty?, :size, :to => :@allocations
|
10
|
+
attr_reader :total
|
11
|
+
|
12
|
+
def initialize allocations = []
|
13
|
+
@allocations = allocations
|
18
14
|
end
|
19
|
-
end
|
20
|
-
# Sort the allocations.
|
21
|
-
#
|
22
|
-
def sort!
|
23
|
-
@allocations.sort!
|
24
|
-
end
|
25
15
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
16
|
+
# Score each allocation.
|
17
|
+
#
|
18
|
+
def calculate_score weights
|
19
|
+
@allocations.each do |allocation|
|
20
|
+
allocation.calculate_score weights
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# Sort the allocations.
|
24
|
+
#
|
25
|
+
def sort!
|
26
|
+
@allocations.sort!
|
27
|
+
end
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
@allocations.each { |allocation| allocation.keep identifiers } unless identifiers.empty?
|
38
|
-
end
|
39
|
-
# Removes combinations.
|
40
|
-
#
|
41
|
-
# Only those passed in are removed.
|
42
|
-
#
|
43
|
-
def remove identifiers = []
|
44
|
-
@allocations.each { |allocation| allocation.remove identifiers } unless identifiers.empty?
|
45
|
-
end
|
29
|
+
# Reduces the amount of allocations to x.
|
30
|
+
#
|
31
|
+
def reduce_to amount
|
32
|
+
@allocations = @allocations.shift amount
|
33
|
+
end
|
46
34
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
35
|
+
# Keeps combinations.
|
36
|
+
#
|
37
|
+
# Only those passed in remain.
|
38
|
+
#
|
39
|
+
def keep identifiers = []
|
40
|
+
@allocations.each { |allocation| allocation.keep identifiers } unless identifiers.empty?
|
41
|
+
end
|
42
|
+
# Removes combinations.
|
43
|
+
#
|
44
|
+
# Only those passed in are removed.
|
45
|
+
#
|
46
|
+
def remove identifiers = []
|
47
|
+
@allocations.each { |allocation| allocation.remove identifiers } unless identifiers.empty?
|
52
48
|
end
|
53
|
-
end
|
54
49
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# Parameters:
|
61
|
-
# * amount: the amount of ids to calculate
|
62
|
-
# * offset: the offset from where in the result set to take the ids
|
63
|
-
#
|
64
|
-
# Note: With an amount of 0, an offset > 0 doesn't make much
|
65
|
-
# sense, as seen in the live search.
|
66
|
-
#
|
67
|
-
# Note: Each allocation caches its count, but not its ids (thrown away).
|
68
|
-
# The ids are cached in this class.
|
69
|
-
#
|
70
|
-
# Note: It's possible that no ids are returned by an allocation, but a count. (In case of an offset)
|
71
|
-
#
|
72
|
-
def process! amount, offset = 0
|
73
|
-
@total = 0
|
74
|
-
current_offset = 0
|
75
|
-
@allocations.each do |allocation|
|
76
|
-
ids = allocation.process! amount, offset
|
77
|
-
@total = @total + allocation.count # the total mixed in
|
78
|
-
if ids.empty?
|
79
|
-
offset = offset - allocation.count unless offset.zero?
|
80
|
-
else
|
81
|
-
amount = amount - ids.size # we need less results from the following allocation
|
82
|
-
offset = 0 # we have already passed the offset
|
50
|
+
# Returns the top amount ids.
|
51
|
+
#
|
52
|
+
def ids amount = 20
|
53
|
+
@allocations.inject([]) do |total, allocation|
|
54
|
+
total.size >= amount ? (return total.shift(amount)) : total + allocation.ids
|
83
55
|
end
|
84
56
|
end
|
85
|
-
end
|
86
57
|
|
87
|
-
|
88
|
-
|
89
|
-
|
58
|
+
# This is the main method of this class that will replace ids and count.
|
59
|
+
#
|
60
|
+
# What it does is calculate the ids and counts of its allocations
|
61
|
+
# for being used in the results. It also calculates the total
|
62
|
+
#
|
63
|
+
# Parameters:
|
64
|
+
# * amount: the amount of ids to calculate
|
65
|
+
# * offset: the offset from where in the result set to take the ids
|
66
|
+
#
|
67
|
+
# Note: With an amount of 0, an offset > 0 doesn't make much
|
68
|
+
# sense, as seen in the live search.
|
69
|
+
#
|
70
|
+
# Note: Each allocation caches its count, but not its ids (thrown away).
|
71
|
+
# The ids are cached in this class.
|
72
|
+
#
|
73
|
+
# Note: It's possible that no ids are returned by an allocation, but a count. (In case of an offset)
|
74
|
+
#
|
75
|
+
def process! amount, offset = 0
|
76
|
+
@total = 0
|
77
|
+
current_offset = 0
|
78
|
+
@allocations.each do |allocation|
|
79
|
+
ids = allocation.process! amount, offset
|
80
|
+
@total = @total + allocation.count # the total mixed in
|
81
|
+
if ids.empty?
|
82
|
+
offset = offset - allocation.count unless offset.zero?
|
83
|
+
else
|
84
|
+
amount = amount - ids.size # we need less results from the following allocation
|
85
|
+
offset = 0 # we have already passed the offset
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
def uniq
|
91
|
+
@allocations.uniq!
|
92
|
+
end
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
94
|
+
def to_a
|
95
|
+
@allocations
|
96
|
+
end
|
97
|
+
|
98
|
+
# Simply inspects the internal allocations.
|
99
|
+
#
|
100
|
+
def to_s
|
101
|
+
@allocations.inspect
|
102
|
+
end
|
103
|
+
|
104
|
+
# Allocations for results are in the form:
|
105
|
+
# [
|
106
|
+
# allocation1.to_result,
|
107
|
+
# allocation2.to_result
|
108
|
+
# ...
|
109
|
+
# ]
|
110
|
+
#
|
111
|
+
def to_result
|
112
|
+
@allocations.map(&:to_result).compact
|
113
|
+
end
|
100
114
|
|
101
|
-
# Allocations for results are in the form:
|
102
|
-
# [
|
103
|
-
# allocation1.to_result,
|
104
|
-
# allocation2.to_result
|
105
|
-
# ...
|
106
|
-
# ]
|
107
|
-
#
|
108
|
-
def to_result
|
109
|
-
@allocations.map(&:to_result).compact
|
110
115
|
end
|
111
116
|
|
112
117
|
end
|
@@ -1,76 +1,80 @@
|
|
1
|
-
module
|
1
|
+
module Picky
|
2
2
|
|
3
|
-
|
4
|
-
# the index (the bundle): [text, index_bundle]
|
5
|
-
#
|
6
|
-
# A combination is a single part of an allocation:
|
7
|
-
# [..., [text2, index_bundle2], ...]
|
8
|
-
#
|
9
|
-
# An allocation consists of a number of combinations:
|
10
|
-
# [[text1, index_bundle1], [text2, index_bundle2], [text3, index_bundle1]]
|
11
|
-
#
|
12
|
-
class Combination # :nodoc:all
|
3
|
+
module Query
|
13
4
|
|
14
|
-
|
15
|
-
|
16
|
-
def initialize token, category
|
17
|
-
@token = token
|
18
|
-
@category_name = category.name
|
19
|
-
@bundle = category.bundle_for token
|
20
|
-
@text = @token.text # don't want to use reset_similar already
|
21
|
-
end
|
22
|
-
|
23
|
-
# Note: Required for uniq!
|
24
|
-
#
|
25
|
-
def hash
|
26
|
-
[@token.to_s, @bundle].hash
|
27
|
-
end
|
28
|
-
|
29
|
-
# Returns the weight of this combination.
|
30
|
-
#
|
31
|
-
# Note: Caching is most of the time useful.
|
32
|
-
#
|
33
|
-
def weight
|
34
|
-
@weight ||= @bundle.weight(@text)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns an array of ids for the given text.
|
38
|
-
#
|
39
|
-
# Note: Caching is most of the time useful.
|
5
|
+
# Describes the combination of a token (the text) and
|
6
|
+
# the index (the bundle): [text, index_bundle]
|
40
7
|
#
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
# The identifier for this combination.
|
8
|
+
# A combination is a single part of an allocation:
|
9
|
+
# [..., [text2, index_bundle2], ...]
|
46
10
|
#
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
# Is the identifier in the given identifiers?
|
11
|
+
# An allocation consists of a number of combinations:
|
12
|
+
# [[text1, index_bundle1], [text2, index_bundle2], [text3, index_bundle1]]
|
52
13
|
#
|
53
|
-
|
54
|
-
|
55
|
-
|
14
|
+
class Combination # :nodoc:all
|
15
|
+
|
16
|
+
attr_reader :token, :bundle, :category_name
|
17
|
+
|
18
|
+
def initialize token, category
|
19
|
+
@token = token
|
20
|
+
@category_name = category.name
|
21
|
+
@bundle = category.bundle_for token
|
22
|
+
@text = @token.text # don't want to use reset_similar already
|
23
|
+
end
|
24
|
+
|
25
|
+
# Note: Required for uniq!
|
26
|
+
#
|
27
|
+
def hash
|
28
|
+
[@token.to_s, @bundle].hash
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the weight of this combination.
|
32
|
+
#
|
33
|
+
# Note: Caching is most of the time useful.
|
34
|
+
#
|
35
|
+
def weight
|
36
|
+
@weight ||= @bundle.weight(@text)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns an array of ids for the given text.
|
40
|
+
#
|
41
|
+
# Note: Caching is most of the time useful.
|
42
|
+
#
|
43
|
+
def ids
|
44
|
+
@ids ||= @bundle.ids(@text)
|
45
|
+
end
|
46
|
+
|
47
|
+
# The identifier for this combination.
|
48
|
+
#
|
49
|
+
def identifier
|
50
|
+
"#{bundle.identifier}:#{@token.identifier}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Is the identifier in the given identifiers?
|
54
|
+
#
|
55
|
+
def in? identifiers
|
56
|
+
identifiers.include? identifier
|
57
|
+
end
|
58
|
+
|
59
|
+
# Combines the category names with the original names.
|
60
|
+
# [
|
61
|
+
# [:title, 'Flarbl', :flarbl],
|
62
|
+
# [:category, 'Gnorf', :gnorf]
|
63
|
+
# ]
|
64
|
+
#
|
65
|
+
def to_result
|
66
|
+
[@category_name, *@token.to_result]
|
67
|
+
end
|
68
|
+
|
69
|
+
# Example:
|
70
|
+
# "exact title:Peter*:peter"
|
71
|
+
#
|
72
|
+
def to_s
|
73
|
+
"#{bundle.identifier} #{to_result.join(':')}"
|
74
|
+
end
|
56
75
|
|
57
|
-
# Combines the category names with the original names.
|
58
|
-
# [
|
59
|
-
# [:title, 'Flarbl', :flarbl],
|
60
|
-
# [:category, 'Gnorf', :gnorf]
|
61
|
-
# ]
|
62
|
-
#
|
63
|
-
def to_result
|
64
|
-
[@category_name, *@token.to_result]
|
65
|
-
end
|
66
|
-
|
67
|
-
# Example:
|
68
|
-
# "exact title:Peter*:peter"
|
69
|
-
#
|
70
|
-
def to_s
|
71
|
-
"#{bundle.identifier} #{to_result.join(':')}"
|
72
76
|
end
|
73
|
-
|
77
|
+
|
74
78
|
end
|
75
79
|
|
76
80
|
end
|
@@ -1,66 +1,70 @@
|
|
1
|
-
module
|
1
|
+
module Picky
|
2
2
|
|
3
|
-
|
4
|
-
#
|
5
|
-
# They are the core of an allocation.
|
6
|
-
# An allocation consists of a number of combinations.
|
7
|
-
#
|
8
|
-
module Combinations # :nodoc:all
|
3
|
+
module Query
|
9
4
|
|
10
|
-
#
|
5
|
+
# Combinations are a number of Combination-s.
|
11
6
|
#
|
12
|
-
|
7
|
+
# They are the core of an allocation.
|
8
|
+
# An allocation consists of a number of combinations.
|
9
|
+
#
|
10
|
+
module Combinations # :nodoc:all
|
13
11
|
|
14
|
-
|
12
|
+
# Base Combinations contain methods for calculating score and ids.
|
13
|
+
#
|
14
|
+
class Base
|
15
15
|
|
16
|
-
|
16
|
+
attr_reader :combinations
|
17
17
|
|
18
|
-
|
19
|
-
@combinations = combinations
|
20
|
-
end
|
18
|
+
delegate :empty?, :to => :@combinations
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
def initialize combinations = []
|
21
|
+
@combinations = combinations
|
22
|
+
end
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
total_score + weighted_score(weights)
|
30
|
-
end
|
31
|
-
def total_score
|
32
|
-
@combinations.sum &:weight
|
33
|
-
end
|
34
|
-
def weighted_score weights
|
35
|
-
weights.score @combinations
|
36
|
-
end
|
24
|
+
def hash
|
25
|
+
@combinations.hash
|
26
|
+
end
|
37
27
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
28
|
+
# Uses user specific weights to calculate a score for the combinations.
|
29
|
+
#
|
30
|
+
def calculate_score weights
|
31
|
+
total_score + weighted_score(weights)
|
32
|
+
end
|
33
|
+
def total_score
|
34
|
+
@combinations.sum &:weight
|
35
|
+
end
|
36
|
+
def weighted_score weights
|
37
|
+
weights.score @combinations
|
38
|
+
end
|
48
39
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
40
|
+
# Filters the tokens and identifiers such that only identifiers
|
41
|
+
# that are passed in, remain, including their tokens.
|
42
|
+
#
|
43
|
+
# Note: This method is not totally independent of the calculate_ids one.
|
44
|
+
# Since identifiers are only nullified, we need to not include the
|
45
|
+
# ids that have an associated identifier that is nil.
|
46
|
+
#
|
47
|
+
def keep identifiers = []
|
48
|
+
@combinations.reject! { |combination| !combination.in?(identifiers) }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Filters the tokens and identifiers such that identifiers
|
52
|
+
# that are passed in, are removed, including their tokens.
|
53
|
+
#
|
54
|
+
# Note: This method is not totally independent of the calculate_ids one.
|
55
|
+
# Since identifiers are only nullified, we need to not include the
|
56
|
+
# ids that have an associated identifier that is nil.
|
57
|
+
#
|
58
|
+
def remove identifiers = []
|
59
|
+
@combinations.reject! { |combination| combination.in?(identifiers) }
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
#
|
64
|
+
def to_result
|
65
|
+
@combinations.map &:to_result
|
66
|
+
end
|
59
67
|
|
60
|
-
#
|
61
|
-
#
|
62
|
-
def to_result
|
63
|
-
@combinations.map &:to_result
|
64
68
|
end
|
65
69
|
|
66
70
|
end
|