picky 3.6.10 → 3.6.11
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/backends/redis.rb +25 -17
- data/lib/picky/backends/sqlite/array.rb +1 -3
- data/lib/picky/bundle.rb +6 -4
- data/lib/picky/bundle_realtime.rb +17 -15
- data/lib/picky/category.rb +1 -1
- data/lib/picky/console.rb +1 -1
- data/lib/picky/query/combination.rb +3 -3
- data/lib/picky/query/combinations.rb +6 -0
- data/lib/picky/wrappers/category/exact_first.rb +3 -0
- data/spec/functional/backends/memory_bundle_realtime_spec.rb +4 -4
- data/spec/functional/max_allocations_spec.rb +1 -1
- data/spec/lib/backends/redis/directly_manipulable_spec.rb +12 -0
- data/spec/lib/bundle_spec.rb +1 -1
- data/spec/lib/indexed/bundle_spec.rb +1 -1
- data/spec/lib/indexing/bundle_spec.rb +2 -8
- data/spec/lib/query/combination_spec.rb +3 -3
- metadata +20 -20
data/lib/picky/backends/redis.rb
CHANGED
@@ -156,27 +156,35 @@ module Picky
|
|
156
156
|
|
157
157
|
result_id = generate_intermediate_result_id
|
158
158
|
|
159
|
-
#
|
159
|
+
# Little optimization.
|
160
160
|
#
|
161
|
-
|
162
|
-
|
163
|
-
# Return clean and early if there has been no intersection.
|
161
|
+
# TODO Include in the scripting version as well.
|
164
162
|
#
|
165
|
-
if
|
166
|
-
|
167
|
-
|
168
|
-
|
163
|
+
if identifiers.size > 1
|
164
|
+
# Intersect and store.
|
165
|
+
#
|
166
|
+
intersected = client.zinterstore result_id, identifiers
|
169
167
|
|
170
|
-
|
171
|
-
|
172
|
-
|
168
|
+
# Return clean and early if there has been no intersection.
|
169
|
+
#
|
170
|
+
if intersected.zero?
|
171
|
+
client.del result_id
|
172
|
+
return []
|
173
|
+
end
|
173
174
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
175
|
+
# Get the stored result.
|
176
|
+
#
|
177
|
+
results = client.zrange result_id, offset, (offset + amount)
|
178
|
+
|
179
|
+
# Delete the stored result as it was only for temporary purposes.
|
180
|
+
#
|
181
|
+
# Note: I could also not delete it, but that
|
182
|
+
# would not be clean at all.
|
183
|
+
#
|
184
|
+
client.del result_id
|
185
|
+
else
|
186
|
+
results = client.zrange identifiers.first, offset, (offset + amount)
|
187
|
+
end
|
180
188
|
|
181
189
|
results
|
182
190
|
end
|
@@ -25,9 +25,7 @@ module Picky
|
|
25
25
|
res = db.execute "SELECT value FROM key_value WHERE key = ? LIMIT 1",
|
26
26
|
key.to_s
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
array = res.empty? ? [] : Yajl::Parser.parse(res.first.first)
|
28
|
+
array = res.blank? ? [] : Yajl::Parser.parse(res.first.first)
|
31
29
|
DirectlyManipulable.make self, array, key
|
32
30
|
array
|
33
31
|
end
|
data/lib/picky/bundle.rb
CHANGED
@@ -59,7 +59,7 @@ module Picky
|
|
59
59
|
reset_backend
|
60
60
|
end
|
61
61
|
def identifier
|
62
|
-
"#{category.identifier}:#{name}"
|
62
|
+
:"#{category.identifier}:#{name}"
|
63
63
|
end
|
64
64
|
|
65
65
|
# If no specific backend has been set,
|
@@ -127,11 +127,13 @@ module Picky
|
|
127
127
|
def similar text
|
128
128
|
code = similarity_strategy.encoded text
|
129
129
|
similar_codes = code && @similarity[code]
|
130
|
-
if similar_codes
|
131
|
-
|
130
|
+
if similar_codes.blank?
|
131
|
+
[] # Return a simple array.
|
132
|
+
else
|
133
|
+
similar_codes = similar_codes.dup
|
132
134
|
similar_codes.delete text
|
135
|
+
similar_codes
|
133
136
|
end
|
134
|
-
similar_codes || []
|
135
137
|
end
|
136
138
|
|
137
139
|
# If a key format is set, use it, else delegate to the category.
|
@@ -7,21 +7,24 @@ module Picky
|
|
7
7
|
def remove id
|
8
8
|
# Is it anywhere?
|
9
9
|
#
|
10
|
-
|
11
|
-
return unless syms
|
10
|
+
str_or_syms = @realtime[id]
|
12
11
|
|
13
|
-
|
14
|
-
|
12
|
+
return if str_or_syms.blank?
|
13
|
+
|
14
|
+
str_or_syms.each do |str_or_sym|
|
15
|
+
ids = @inverted[str_or_sym]
|
15
16
|
ids.delete id
|
16
17
|
|
17
18
|
if ids.empty?
|
18
|
-
@inverted.delete
|
19
|
-
@weights.delete
|
19
|
+
@inverted.delete str_or_sym
|
20
|
+
@weights.delete str_or_sym
|
21
|
+
|
20
22
|
# Since no element uses this sym anymore, we can delete the similarity for it.
|
21
23
|
# TODO Not really. Since multiple syms can point to the same encoded.
|
22
|
-
|
24
|
+
#
|
25
|
+
@similarity.delete self.similarity_strategy.encoded(str_or_sym)
|
23
26
|
else
|
24
|
-
@weights[
|
27
|
+
@weights[str_or_sym] = self.weights_strategy.weight_for ids.size
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -31,7 +34,7 @@ module Picky
|
|
31
34
|
# Returns a reference to the array where the id has been added.
|
32
35
|
#
|
33
36
|
def add id, str_or_sym, where = :unshift
|
34
|
-
str_or_syms = @realtime[id]
|
37
|
+
str_or_syms = @realtime[id] ||= []
|
35
38
|
|
36
39
|
# Inverted.
|
37
40
|
#
|
@@ -46,7 +49,7 @@ module Picky
|
|
46
49
|
|
47
50
|
# TODO Introduce a new method?
|
48
51
|
#
|
49
|
-
ids = @inverted[str_or_sym]
|
52
|
+
ids = @inverted[str_or_sym] ||= []
|
50
53
|
ids.send where, id
|
51
54
|
end
|
52
55
|
|
@@ -69,12 +72,12 @@ module Picky
|
|
69
72
|
#
|
70
73
|
def add_similarity str_or_sym, where = :unshift
|
71
74
|
if encoded = self.similarity_strategy.encoded(str_or_sym)
|
72
|
-
|
75
|
+
similars = @similarity[encoded] ||= []
|
73
76
|
|
74
77
|
# Not completely correct, as others will also be affected, but meh.
|
75
78
|
#
|
76
|
-
|
77
|
-
|
79
|
+
similars.delete str_or_sym if similars.include? str_or_sym
|
80
|
+
similars.send where, str_or_sym
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
@@ -96,8 +99,7 @@ module Picky
|
|
96
99
|
clear_realtime
|
97
100
|
@inverted.each_pair do |str_or_sym, ids|
|
98
101
|
ids.each do |id|
|
99
|
-
str_or_syms = @realtime[id]
|
100
|
-
str_or_syms = (@realtime[id] = []) unless str_or_syms # TODO Nicefy.
|
102
|
+
str_or_syms = @realtime[id] ||= []
|
101
103
|
@realtime[id] << str_or_sym unless str_or_syms.include? str_or_sym
|
102
104
|
end
|
103
105
|
end
|
data/lib/picky/category.rb
CHANGED
data/lib/picky/console.rb
CHANGED
@@ -46,7 +46,7 @@ module Picky
|
|
46
46
|
# The identifier for this combination.
|
47
47
|
#
|
48
48
|
def identifier
|
49
|
-
"#{category.bundle_for(token).identifier}:#{token.
|
49
|
+
@identifier ||= "#{category.bundle_for(token).identifier}:inverted:#{token.text}"
|
50
50
|
end
|
51
51
|
|
52
52
|
# Note: Required for uniq!
|
@@ -54,7 +54,7 @@ module Picky
|
|
54
54
|
# TODO Ok with category or is the bundle needed?
|
55
55
|
#
|
56
56
|
def hash
|
57
|
-
[token
|
57
|
+
[token, category].hash
|
58
58
|
end
|
59
59
|
|
60
60
|
# Combines the category names with the original names.
|
@@ -71,7 +71,7 @@ module Picky
|
|
71
71
|
# "exact title:Peter*:peter"
|
72
72
|
#
|
73
73
|
def to_s
|
74
|
-
"#{category.bundle_for(token).identifier}
|
74
|
+
"#{category.bundle_for(token).identifier}(#{to_result.join(':')})"
|
75
75
|
end
|
76
76
|
|
77
77
|
end
|
@@ -17,16 +17,16 @@ describe Picky::Bundle do
|
|
17
17
|
backend: Picky::Backends::Memory.new
|
18
18
|
end
|
19
19
|
|
20
|
-
it 'is by default
|
20
|
+
it 'is by default a Hash' do
|
21
21
|
@bundle.realtime.should be_kind_of(Hash)
|
22
22
|
end
|
23
|
-
it 'is by default
|
23
|
+
it 'is by default a Hash' do
|
24
24
|
@bundle.inverted.should be_kind_of(Hash)
|
25
25
|
end
|
26
|
-
it 'is by default
|
26
|
+
it 'is by default a Hash' do
|
27
27
|
@bundle.weights.should be_kind_of(Hash)
|
28
28
|
end
|
29
|
-
it 'is by default
|
29
|
+
it 'is by default a Hash' do
|
30
30
|
@bundle.similarity.should be_kind_of(Hash)
|
31
31
|
end
|
32
32
|
|
@@ -10,6 +10,18 @@ describe Picky::Backends::Redis::DirectlyManipulable do
|
|
10
10
|
list
|
11
11
|
end
|
12
12
|
|
13
|
+
context 'problem cases' do
|
14
|
+
it 'does not dup its special abilities' do
|
15
|
+
list = [1,2]
|
16
|
+
described_class.make backend, list, 'some:key'
|
17
|
+
dupped_list = list.dup
|
18
|
+
|
19
|
+
client.should_receive(:zadd).never
|
20
|
+
|
21
|
+
dupped_list << 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
13
25
|
context 'stubbed backend' do
|
14
26
|
before(:each) do
|
15
27
|
backend.stub! :[]
|
data/spec/lib/bundle_spec.rb
CHANGED
@@ -11,8 +11,8 @@ describe Picky::Bundle do
|
|
11
11
|
let(:bundle) { described_class.new :some_name, @category, @weights, :some_partial, @similarity }
|
12
12
|
|
13
13
|
describe 'identifier' do
|
14
|
-
it '
|
15
|
-
bundle.identifier.should == 'some_index:some_category:some_name'
|
14
|
+
it 'should return a specific identifier' do
|
15
|
+
bundle.identifier.should == :'some_index:some_category:some_name'
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -35,12 +35,6 @@ describe Picky::Bundle do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
describe 'identifier' do
|
39
|
-
it 'should return a specific identifier' do
|
40
|
-
bundle.identifier.should == 'some_index:some_category:some_name'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
38
|
describe 'dump' do
|
45
39
|
it 'should trigger dumps' do
|
46
40
|
bundle.stub! :timed_exclaim
|
@@ -19,13 +19,13 @@ describe Picky::Query::Combination do
|
|
19
19
|
it "shows the combination's info" do
|
20
20
|
@token.stub! :to_result => :token_result
|
21
21
|
|
22
|
-
@combination.to_s.should == 'bundle_name
|
22
|
+
@combination.to_s.should == 'bundle_name(some_category_name:token_result)'
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe 'hash' do
|
27
27
|
it 'should hash the token and the bundle' do
|
28
|
-
@combination.hash.should == [@token
|
28
|
+
@combination.hash.should == [@token, @category].hash
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -49,7 +49,7 @@ describe Picky::Query::Combination do
|
|
49
49
|
|
50
50
|
describe 'identifier' do
|
51
51
|
it 'should get the category name from the bundle' do
|
52
|
-
@combination.identifier.should == "bundle_name:
|
52
|
+
@combination.identifier.should == "bundle_name:inverted:some_text"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: picky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.11
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-11-30 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70356380283200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,21 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70356380283200
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: picky-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &70356380282520 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 3.6.
|
32
|
+
version: 3.6.11
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70356380282520
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rack
|
38
|
-
requirement: &
|
38
|
+
requirement: &70356380282100 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70356380282100
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rack_fast_escape
|
49
|
-
requirement: &
|
49
|
+
requirement: &70356380281640 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70356380281640
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: text
|
60
|
-
requirement: &
|
60
|
+
requirement: &70356380281200 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70356380281200
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yajl-ruby
|
71
|
-
requirement: &
|
71
|
+
requirement: &70356380280720 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70356380280720
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: activesupport
|
82
|
-
requirement: &
|
82
|
+
requirement: &70356380280220 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '3.0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70356380280220
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: unicorn
|
93
|
-
requirement: &
|
93
|
+
requirement: &70356380279800 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70356380279800
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: sinatra
|
104
|
-
requirement: &
|
104
|
+
requirement: &70356380279340 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :runtime
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70356380279340
|
113
113
|
description: Fast Ruby semantic text search engine with comfortable single field interface.
|
114
114
|
email: florian.hanke+picky@gmail.com
|
115
115
|
executables:
|