picky 4.26.2 → 4.27.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3a6133019bb7fb372e2ef9a8261ee69df1e562b
4
- data.tar.gz: 8dfb39edf77042b40276bc0e26d34286c3e71b79
3
+ metadata.gz: 20377f0b4ac92cd75659306842de34204b7bf85d
4
+ data.tar.gz: 7c3e252193f4be20dd6fb5013b11a9d427662051
5
5
  SHA512:
6
- metadata.gz: d21d378abbbd2ea37ca0eb6ce1e948c5904db3daa6f6df41797a6acaff996e12fcf43cf5c5cc536694d0883c5918ca6a1049fe22eed369ba563f495688999cef
7
- data.tar.gz: 50ca4ff1812761a21af2c5aaa781f75bddfd4fbe20a8de72334f660a826eba3c551933c56924e2415af7eebd240ce33aea588207700cc38c1a2ea27db04e5573
6
+ metadata.gz: 02e007ee3b0e7be2a4ce3c337bde4d496c4ccce05450196d8e7135d69d08dec5020d4fa8858b58ae54e170b64fd62677bd08df6c7eb348ada0c78252b7effbd2
7
+ data.tar.gz: 41285d5f985a0ed59407ba0b8f52526f122a86af8be4f90341b39d79884a2b922d9883a16ae39f0f6ecb997fb5edd1e5208c960d8811dedd09b1c22821c3bb8f
@@ -12,37 +12,23 @@ module Picky
12
12
 
13
13
  # Returns an object that on #initial, #load returns
14
14
  # an object that responds to:
15
- # [:token] # => [id, id, id, id, id] (an array of ids)
15
+ # object[:token] # => [id, id, id, id, id] (an array of ids)
16
16
  #
17
- def create_inverted bundle
17
+ def create_inverted bundle, _ = nil
18
18
  json bundle.index_path(:inverted)
19
19
  end
20
20
  # Returns an object that on #initial, #load returns
21
21
  # an object that responds to:
22
- # [:token] # => 1.23 (a weight)
22
+ # object[:key] # => value (a value for this config key)
23
23
  #
24
- # def create_weights bundle
25
- # json bundle.index_path(:weights)
26
- # end
27
- # # Returns an object that on #initial, #load returns
28
- # # an object that responds to:
29
- # # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
30
- # #
31
- # def create_similarity bundle
32
- # Marshal.new bundle.index_path(:similarity)
33
- # end
34
- # Returns an object that on #initial, #load returns
35
- # an object that responds to:
36
- # [:key] # => value (a value for this config key)
37
- #
38
- def create_configuration bundle
24
+ def create_configuration bundle, _ = nil
39
25
  json bundle.index_path(:configuration)
40
26
  end
41
27
  # Returns an object that on #initial, #load returns
42
28
  # an object that responds to:
43
- # [id] # => [:sym1, :sym2]
29
+ # object[id] # => [:sym1, :sym2]
44
30
  #
45
- def create_realtime bundle
31
+ def create_realtime bundle, _ = nil
46
32
  json bundle.index_path(:realtime)
47
33
  end
48
34
 
@@ -10,11 +10,11 @@ module Picky
10
10
  #
11
11
  class File < Backend
12
12
 
13
- def create_weights bundle
13
+ def create_weights bundle, _ = nil
14
14
  Memory::JSON.new bundle.index_path(:weights)
15
15
  end
16
16
 
17
- def create_similarity bundle
17
+ def create_similarity bundle, _ = nil
18
18
  json bundle.index_path(:similarity)
19
19
  end
20
20
 
@@ -0,0 +1,46 @@
1
+ if require 'google_hash'
2
+
3
+ class ::GoogleHashSparseRubyToRuby
4
+
5
+ # This is mainly used in tests, which is
6
+ # why we allow for a silly implementation.
7
+ #
8
+ def == hash
9
+ return false unless hash.respond_to?(:to_h)
10
+
11
+ self.each do |key, value|
12
+ return false if hash[key] != value
13
+ end
14
+ hash.each do |key, value|
15
+ return false if self[key] != value
16
+ end
17
+
18
+ true
19
+ end
20
+
21
+ # I am a hashy thing.
22
+ #
23
+ def to_hash
24
+ true
25
+ end
26
+
27
+ #
28
+ #
29
+ def inject init, &block
30
+ result = init
31
+ each do |key, value|
32
+ result = block.call result, [key, value]
33
+ end
34
+ result
35
+ end
36
+
37
+ def size
38
+ result = 0
39
+ # each only accepts a block
40
+ each { result += 1 }
41
+ result
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -18,12 +18,17 @@ module Picky
18
18
  # This file's location.
19
19
  #
20
20
  attr_reader :cache_path
21
+
22
+ # What hash type to use. Default: ::Hash
23
+ #
24
+ attr_reader :hash_type
21
25
 
22
26
  # An index cache takes a path, without file extension,
23
27
  # which will be provided by the subclasses.
24
28
  #
25
- def initialize cache_path, options = {}
29
+ def initialize cache_path, hash_type = Hash, options = {}
26
30
  @cache_path = "#{cache_path}.memory.#{extension}"
31
+ @hash_type = hash_type
27
32
  @empty = options[:empty]
28
33
  @initial = options[:initial]
29
34
  end
@@ -38,7 +43,7 @@ module Picky
38
43
  # together before it is dumped into the files.
39
44
  #
40
45
  def empty
41
- @empty && @empty.clone || empty_hash
46
+ @empty && @empty.clone || hash_type.new
42
47
  end
43
48
 
44
49
  def empty_hash
@@ -50,10 +55,10 @@ module Picky
50
55
  end
51
56
  end
52
57
 
53
- # The initial content before loading from file.
58
+ # The initial content before loading from file/indexing.
54
59
  #
55
60
  def initial
56
- @initial && @initial.clone || {}
61
+ @initial && @initial.clone || hash_type.new
57
62
  end
58
63
 
59
64
  # Deletes the file.
@@ -4,13 +4,58 @@ module Picky
4
4
 
5
5
  class Memory < Backend
6
6
 
7
- def create_weights bundle
8
- JSON.new bundle.index_path(:weights)
7
+ # TODO Make lazy.
8
+ require_relative 'google_hash'
9
+
10
+ # Returns an object that on #initial, #load returns
11
+ # an object that responds to:
12
+ # object[:token] # => [id, id, id, id, id] (an array of ids)
13
+ #
14
+ def create_inverted bundle, hints = nil
15
+ json bundle.index_path(:inverted), hash_for(hints)
16
+ end
17
+
18
+ # Returns an object that on #initial, #load returns
19
+ # an object that responds to:
20
+ # object[:token] # => 1.23 (a weight)
21
+ #
22
+ def create_weights bundle, hints = nil
23
+ JSON.new bundle.index_path(:weights), hash_for(hints) # GoogleHashSparseRubyToInt (I wish they had floats)
24
+ end
25
+
26
+ # Returns an object that on #initial, #load returns
27
+ # an object that responds to:
28
+ # object[:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
29
+ #
30
+ def create_similarity bundle, hints = nil
31
+ Marshal.new bundle.index_path(:similarity), hash_for(hints)
9
32
  end
10
33
 
11
- def create_similarity bundle
12
- Marshal.new bundle.index_path(:similarity)
34
+ # Returns an object that on #initial, #load returns
35
+ # an object that responds to:
36
+ # object[:key] # => value (a value for this config key)
37
+ #
38
+ def create_configuration bundle, hints = nil
39
+ json bundle.index_path(:configuration), hash_for(hints)
13
40
  end
41
+
42
+ # Returns an object that on #initial, #load returns
43
+ # an object that responds to:
44
+ # object[id] # => [:sym1, :sym2]
45
+ #
46
+ def create_realtime bundle, hints = nil
47
+ json bundle.index_path(:realtime), hash_for(hints) # GoogleHashSparseLongToRuby # FIXME This is only true on number keys (add Picky hints).
48
+ end
49
+
50
+ private
51
+
52
+ def hash_for hints
53
+ if hints && hints.does?(:no_dump)
54
+ ::GoogleHashSparseRubyToRuby
55
+ else
56
+ ::Hash
57
+ end
58
+ end
14
59
 
15
60
  end
16
61
 
@@ -36,31 +36,31 @@ module Picky
36
36
  # Returns an object that on #initial, #load returns an object that responds to:
37
37
  # [:token] # => [id, id, id, id, id] (an array of ids)
38
38
  #
39
- def create_inverted bundle
39
+ def create_inverted bundle, _ = nil
40
40
  List.new client, "#{PICKY_ENVIRONMENT}:#{bundle.identifier}:inverted", realtime: realtime
41
41
  end
42
42
  # Returns an object that on #initial, #load returns an object that responds to:
43
43
  # [:token] # => 1.23 (a weight)
44
44
  #
45
- def create_weights bundle
45
+ def create_weights bundle, _ = nil
46
46
  Float.new client, "#{PICKY_ENVIRONMENT}:#{bundle.identifier}:weights", realtime: realtime
47
47
  end
48
48
  # Returns an object that on #initial, #load returns an object that responds to:
49
49
  # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
50
50
  #
51
- def create_similarity bundle
51
+ def create_similarity bundle, _ = nil
52
52
  List.new client, "#{PICKY_ENVIRONMENT}:#{bundle.identifier}:similarity", realtime: realtime
53
53
  end
54
54
  # Returns an object that on #initial, #load returns an object that responds to:
55
55
  # [:key] # => value (a value for this config key)
56
56
  #
57
- def create_configuration bundle
57
+ def create_configuration bundle, _ = nil
58
58
  String.new client, "#{PICKY_ENVIRONMENT}:#{bundle.identifier}:configuration", realtime: realtime
59
59
  end
60
60
  # Returns an object that on #initial, #load returns an object that responds to:
61
61
  # [id] # => [:sym1, :sym2]
62
62
  #
63
- def create_realtime bundle
63
+ def create_realtime bundle, _ = nil
64
64
  List.new client, "#{PICKY_ENVIRONMENT}:#{bundle.identifier}:realtime", realtime: realtime
65
65
  end
66
66
 
@@ -17,31 +17,31 @@ module Picky
17
17
  # Returns an object that on #initial, #load returns an object that responds to:
18
18
  # [:token] # => [id, id, id, id, id] (an array of ids)
19
19
  #
20
- def create_inverted bundle
20
+ def create_inverted bundle, _ = nil
21
21
  StringKeyArray.new bundle.index_path(:inverted), realtime: realtime
22
22
  end
23
23
  # Returns an object that on #initial, #load returns an object that responds to:
24
24
  # [:token] # => 1.23 (a weight)
25
25
  #
26
- def create_weights bundle
26
+ def create_weights bundle, _ = nil
27
27
  Value.new bundle.index_path(:weights), realtime: realtime
28
28
  end
29
29
  # Returns an object that on #initial, #load returns an object that responds to:
30
30
  # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
31
31
  #
32
- def create_similarity bundle
32
+ def create_similarity bundle, _ = nil
33
33
  StringKeyArray.new bundle.index_path(:similarity), realtime: realtime
34
34
  end
35
35
  # Returns an object that on #initial, #load returns an object that responds to:
36
36
  # [:key] # => value (a value for this config key)
37
37
  #
38
- def create_configuration bundle
38
+ def create_configuration bundle, _ = nil
39
39
  Value.new bundle.index_path(:configuration), realtime: realtime
40
40
  end
41
41
  # Returns an object that on #initial, #load returns an object that responds to:
42
42
  # [id] # => [:sym1, :sym2]
43
43
  #
44
- def create_realtime bundle
44
+ def create_realtime bundle, _ = nil
45
45
  IntegerKeyArray.new bundle.index_path(:realtime), realtime: realtime
46
46
  end
47
47
 
data/lib/picky/bundle.rb CHANGED
@@ -53,7 +53,8 @@ module Picky
53
53
  @weight_strategy = weight_strategy
54
54
  @partial_strategy = partial_strategy
55
55
  @similarity_strategy = similarity_strategy
56
-
56
+
57
+ @hints = options.delete :hints
57
58
  @backend = options.delete :backend
58
59
 
59
60
  reset_backend
@@ -81,11 +82,11 @@ module Picky
81
82
  # TODO Move @backend_ into the backend?
82
83
  #
83
84
  def create_backends
84
- @backend_inverted = backend.create_inverted self
85
- @backend_weights = backend.create_weights self
86
- @backend_similarity = backend.create_similarity self
87
- @backend_configuration = backend.create_configuration self
88
- @backend_realtime = backend.create_realtime self
85
+ @backend_inverted = backend.create_inverted self, @hints
86
+ @backend_weights = backend.create_weights self, @hints
87
+ @backend_similarity = backend.create_similarity self, @hints
88
+ @backend_configuration = backend.create_configuration self, @hints
89
+ @backend_realtime = backend.create_realtime self, @hints
89
90
  end
90
91
 
91
92
  # Initial indexes.
@@ -36,6 +36,10 @@ module Picky
36
36
  def initialize name, index, options = {}
37
37
  @name = name
38
38
  @index = index
39
+
40
+ # TODO Move.
41
+ #
42
+ options[:hints] = index.hints
39
43
 
40
44
  configure_from options
41
45
  configure_indexes_from options
@@ -77,7 +81,19 @@ module Picky
77
81
  #
78
82
  # TODO Rewrite it such that this does not need to be maintained separately (and gets available options automatically).
79
83
  #
80
- @@known_keys = [:indexing, :partial, :qualifier, :qualifiers, :ranging, :similarity, :source, :tokenize, :tokenizer, :weight]
84
+ @@known_keys = [
85
+ :hints,
86
+ :indexing,
87
+ :partial,
88
+ :qualifier,
89
+ :qualifiers,
90
+ :ranging,
91
+ :similarity,
92
+ :source,
93
+ :tokenize,
94
+ :tokenizer,
95
+ :weight,
96
+ ]
81
97
  def warn_if_unknown options
82
98
  if options && (options.keys - @@known_keys).size > 0
83
99
  warn <<-WARNING
@@ -0,0 +1,37 @@
1
+ module Picky
2
+ class Index
3
+
4
+ class Hints
5
+
6
+ def initialize hints
7
+ @hints = check hints
8
+ end
9
+
10
+ # Check if all hints are allowed
11
+ #
12
+ @@allowed_hints = [:no_dump]
13
+ def check hints
14
+ hints.each do |hint|
15
+ unless @@allowed_hints.include?(hint)
16
+ raise <<-ERROR
17
+ Picky cannot optimize for #{hint}.
18
+ Allowed hints are:
19
+ #{@@allowed_hints.join("\n")}
20
+ ERROR
21
+ end
22
+ end
23
+ hints
24
+ end
25
+
26
+ # Tells us if the user intends to e.g. not dump the indexes.
27
+ #
28
+ # E.g. hints.does?(:no_dump) # => true/false
29
+ #
30
+ def does? hint
31
+ @hints.include? hint
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
data/lib/picky/index.rb CHANGED
@@ -87,7 +87,8 @@ module Picky
87
87
  class Index
88
88
 
89
89
  attr_reader :name,
90
- :categories
90
+ :categories,
91
+ :hints
91
92
 
92
93
  forward :[],
93
94
  :dump,
@@ -126,6 +127,13 @@ module Picky
126
127
 
127
128
  instance_eval(&Proc.new) if block_given?
128
129
  end
130
+
131
+ # Provide hints for Picky so it can optimise.
132
+ #
133
+ def optimize *hints
134
+ require_relative 'index/hints'
135
+ @hints = Hints.new hints
136
+ end
129
137
 
130
138
  # TODO Doc.
131
139
  #
@@ -17,17 +17,17 @@ describe Picky::Bundle do
17
17
  backend: Picky::Backends::Memory.new
18
18
  end
19
19
 
20
- it 'is by default a Hash' do
21
- @bundle.realtime.should be_kind_of(Hash)
20
+ it 'is by default Hash-like' do
21
+ @bundle.realtime.should respond_to(:to_hash)
22
22
  end
23
- it 'is by default a Hash' do
24
- @bundle.inverted.should be_kind_of(Hash)
23
+ it 'is by default Hash-like' do
24
+ @bundle.inverted.should respond_to(:to_hash)
25
25
  end
26
- it 'is by default a Hash' do
27
- @bundle.weights.should be_kind_of(Hash)
26
+ it 'is by default Hash-like' do
27
+ @bundle.weights.should respond_to(:to_hash)
28
28
  end
29
- it 'is by default a Hash' do
30
- @bundle.similarity.should be_kind_of(Hash)
29
+ it 'is by default Hash-like' do
30
+ @bundle.similarity.should respond_to(:to_hash)
31
31
  end
32
32
 
33
33
  context 'strings' do
@@ -5,19 +5,19 @@ require 'spec_helper'
5
5
  # To test the interface definition.
6
6
  #
7
7
  class BackendInterfaceTester < Picky::Backends::Backend
8
- def create_inverted _
8
+ def create_inverted _, _ = nil
9
9
  InternalBackendInterfaceTester.new
10
10
  end
11
- def create_weights _
11
+ def create_weights _, _ = nil
12
12
  InternalBackendInterfaceTester.new
13
13
  end
14
- def create_similarity _
14
+ def create_similarity _, _ = nil
15
15
  InternalBackendInterfaceTester.new
16
16
  end
17
- def create_configuration _
17
+ def create_configuration _, _ = nil
18
18
  InternalBackendInterfaceTester.new
19
19
  end
20
- def create_realtime _
20
+ def create_realtime _, _ = nil
21
21
  InternalBackendInterfaceTester.new
22
22
  end
23
23
  end
@@ -174,14 +174,14 @@ describe 'facets' do
174
174
  end
175
175
  it 'has two filtered facets' do
176
176
  finder.facets(:surname, filter: 'age:40 name:peter', counts: false).should == [
177
- 'kunz',
178
- 'hanke'
177
+ 'hanke',
178
+ 'kunz'
179
179
  ]
180
180
  end
181
181
  it 'has 2 facets >= count 1' do
182
182
  finder.facets(:surname, filter: 'age:40 name:peter', at_least: 1, counts: false).should == [
183
- 'kunz',
184
- 'hanke'
183
+ 'hanke',
184
+ 'kunz'
185
185
  ]
186
186
  end
187
187
  it 'has 0 facets >= counts 2' do
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+ require 'ostruct'
5
+
6
+ describe "Hint: no_dump" do
7
+
8
+ Book = Struct.new(:id, :title, :author)
9
+
10
+ let(:index) do
11
+ Picky::Index.new :no_dump do
12
+ optimize :no_dump
13
+
14
+ category :title
15
+ category :author
16
+ end
17
+ end
18
+ let(:try) { Picky::Search.new index }
19
+
20
+ it 'can index and search' do
21
+ index.replace Book.new(2, "Title", "Author")
22
+
23
+ try.search("title:title").ids.should == [2]
24
+ end
25
+
26
+ context 'dumping and loading' do
27
+ it "raises" do
28
+ index.replace Book.new(2, "Title New", "Author New")
29
+
30
+ index.dump
31
+ index.load
32
+ index.build_realtime_mapping
33
+ end
34
+ end
35
+
36
+ end
@@ -27,6 +27,7 @@ describe Picky::Backends::Memory::Basic do
27
27
  context 'with options' do
28
28
  let(:basic) do
29
29
  described_class.new 'spec/temp/some/cache/path/to/file',
30
+ Hash,
30
31
  empty: [],
31
32
  initial: []
32
33
  end
@@ -52,7 +52,7 @@ describe Picky::Category do
52
52
  category.should_receive(:warn).once.with <<-WARNING
53
53
 
54
54
  Warning: Category options {:weights=>:some_weight} for category some_category contain an unknown option.
55
- Working options are: [:indexing, :partial, :qualifier, :qualifiers, :ranging, :similarity, :source, :tokenize, :tokenizer, :weight].
55
+ Working options are: [:hints, :indexing, :partial, :qualifier, :qualifiers, :ranging, :similarity, :source, :tokenize, :tokenizer, :weight].
56
56
  WARNING
57
57
 
58
58
  category.warn_if_unknown :weights => :some_weight
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: 4.26.2
4
+ version: 4.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Hanke
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2009.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: google_hash
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
55
69
  description: Fast Ruby semantic text search engine with comfortable single field interface.
56
70
  email: florian.hanke+picky@gmail.com
57
71
  executables:
@@ -73,6 +87,7 @@ files:
73
87
  - lib/picky/backends/file.rb
74
88
  - lib/picky/backends/file/basic.rb
75
89
  - lib/picky/backends/file/json.rb
90
+ - lib/picky/backends/google_hash.rb
76
91
  - lib/picky/backends/helpers/file.rb
77
92
  - lib/picky/backends/memory.rb
78
93
  - lib/picky/backends/memory/basic.rb
@@ -147,6 +162,7 @@ files:
147
162
  - lib/picky/helpers/indexing.rb
148
163
  - lib/picky/helpers/measuring.rb
149
164
  - lib/picky/index.rb
165
+ - lib/picky/index/hints.rb
150
166
  - lib/picky/index_convenience.rb
151
167
  - lib/picky/index_facets.rb
152
168
  - lib/picky/index_indexed.rb
@@ -234,6 +250,7 @@ files:
234
250
  - spec/functional/ignore_spec.rb
235
251
  - spec/functional/max_allocations_spec.rb
236
252
  - spec/functional/multi_index_qualifier_spec.rb
253
+ - spec/functional/no_dump_hint_spec.rb
237
254
  - spec/functional/no_tokenize_spec.rb
238
255
  - spec/functional/non_specific_ids_larger_than_20_spec.rb
239
256
  - spec/functional/object_use_spec.rb
@@ -417,6 +434,7 @@ test_files:
417
434
  - spec/functional/ignore_spec.rb
418
435
  - spec/functional/max_allocations_spec.rb
419
436
  - spec/functional/multi_index_qualifier_spec.rb
437
+ - spec/functional/no_dump_hint_spec.rb
420
438
  - spec/functional/no_tokenize_spec.rb
421
439
  - spec/functional/non_specific_ids_larger_than_20_spec.rb
422
440
  - spec/functional/object_use_spec.rb