picky 3.0.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/lib/picky/application.rb +12 -12
  2. data/lib/picky/backends/backend.rb +17 -0
  3. data/lib/picky/{backend → backends}/file/basic.rb +1 -1
  4. data/lib/picky/{backend → backends}/file/json.rb +1 -1
  5. data/lib/picky/{backend → backends}/file/marshal.rb +1 -1
  6. data/lib/picky/{backend → backends}/file/text.rb +1 -1
  7. data/lib/picky/backends/memory.rb +53 -0
  8. data/lib/picky/{backend → backends}/redis/basic.rb +9 -14
  9. data/lib/picky/backends/redis/float_hash.rb +26 -0
  10. data/lib/picky/{backend → backends}/redis/list_hash.rb +7 -11
  11. data/lib/picky/{backend → backends}/redis/string_hash.rb +7 -11
  12. data/lib/picky/backends/redis.rb +87 -0
  13. data/lib/picky/bundle.rb +107 -11
  14. data/lib/picky/category.rb +5 -5
  15. data/lib/picky/index.rb +329 -0
  16. data/lib/picky/index_indexed.rb +31 -0
  17. data/lib/picky/index_indexing.rb +161 -0
  18. data/lib/picky/indexed/bundle.rb +112 -0
  19. data/lib/picky/indexed/wrappers/exact_first.rb +1 -1
  20. data/lib/picky/indexers/parallel.rb +2 -1
  21. data/lib/picky/indexers/serial.rb +2 -1
  22. data/lib/picky/indexes_indexing.rb +1 -1
  23. data/lib/picky/indexing/bundle.rb +188 -0
  24. data/lib/picky/indexing/wrappers/category/location.rb +1 -1
  25. data/lib/picky/interfaces/live_parameters.rb +8 -8
  26. data/lib/picky/loader.rb +24 -38
  27. data/lib/picky/migrations/from_30_to_31.rb +61 -0
  28. data/lib/picky/query/allocation.rb +10 -5
  29. data/lib/picky/query/combinations.rb +70 -0
  30. data/lib/picky/query/indexes.rb +8 -7
  31. data/lib/picky/query/indexes_check.rb +47 -0
  32. data/lib/picky/query/token.rb +16 -29
  33. data/lib/picky/query/tokens.rb +4 -20
  34. data/lib/picky/search.rb +51 -58
  35. data/lib/picky/tokenizer.rb +231 -0
  36. data/lib/picky/tokenizers/location.rb +1 -1
  37. data/lib/tasks/try.rake +4 -12
  38. data/lib/tasks/try.rb +37 -0
  39. data/spec/lib/application_spec.rb +5 -5
  40. data/spec/lib/{backend → backends}/file/basic_spec.rb +2 -2
  41. data/spec/lib/{backend → backends}/file/json_spec.rb +2 -2
  42. data/spec/lib/{backend → backends}/file/marshal_spec.rb +2 -2
  43. data/spec/lib/{backend → backends}/file/text_spec.rb +1 -1
  44. data/spec/lib/backends/memory_spec.rb +77 -0
  45. data/spec/lib/{backend → backends}/redis/basic_spec.rb +19 -21
  46. data/spec/lib/backends/redis/float_hash_spec.rb +38 -0
  47. data/spec/lib/backends/redis/list_hash_spec.rb +27 -0
  48. data/spec/lib/backends/redis/string_hash_spec.rb +38 -0
  49. data/spec/lib/backends/redis_spec.rb +79 -0
  50. data/spec/lib/categories_indexed_spec.rb +3 -3
  51. data/spec/lib/category_indexed_spec.rb +6 -6
  52. data/spec/lib/category_indexing_spec.rb +1 -1
  53. data/spec/lib/category_spec.rb +1 -1
  54. data/spec/lib/frontend_adapters/rack_spec.rb +2 -2
  55. data/spec/lib/{indexes/index_indexed_spec.rb → index_indexed_spec.rb} +1 -1
  56. data/spec/lib/{indexes/index_indexing_spec.rb → index_indexing_spec.rb} +1 -1
  57. data/spec/lib/{indexes/index_spec.rb → index_spec.rb} +1 -1
  58. data/spec/lib/indexed/{bundle/memory_spec.rb → memory_spec.rb} +18 -18
  59. data/spec/lib/indexed/wrappers/exact_first_spec.rb +2 -2
  60. data/spec/lib/indexing/{bundle/memory_partial_generation_speed_spec.rb → bundle_partial_generation_speed_spec.rb} +3 -3
  61. data/spec/lib/indexing/bundle_spec.rb +302 -0
  62. data/spec/lib/query/allocation_spec.rb +21 -11
  63. data/spec/lib/query/combination_spec.rb +2 -2
  64. data/spec/lib/query/{combinations/base_spec.rb → combinations_spec.rb} +1 -1
  65. data/spec/lib/query/indexes_check_spec.rb +25 -0
  66. data/spec/lib/query/indexes_spec.rb +5 -1
  67. data/spec/lib/query/token_spec.rb +18 -20
  68. data/spec/lib/query/tokens_spec.rb +14 -65
  69. data/spec/lib/search_spec.rb +36 -37
  70. data/spec/lib/tasks/try_spec.rb +51 -0
  71. data/spec/lib/{tokenizers/base_spec.rb → tokenizer_spec.rb} +15 -44
  72. metadata +64 -81
  73. data/lib/picky/backend/base.rb +0 -121
  74. data/lib/picky/backend/files.rb +0 -28
  75. data/lib/picky/backend/redis.rb +0 -44
  76. data/lib/picky/indexed/bundle/base.rb +0 -47
  77. data/lib/picky/indexed/bundle/memory.rb +0 -88
  78. data/lib/picky/indexed/bundle/redis.rb +0 -91
  79. data/lib/picky/indexes/index.rb +0 -328
  80. data/lib/picky/indexes/index_indexed.rb +0 -35
  81. data/lib/picky/indexes/index_indexing.rb +0 -165
  82. data/lib/picky/indexes/memory.rb +0 -20
  83. data/lib/picky/indexes/redis.rb +0 -20
  84. data/lib/picky/indexing/bundle/base.rb +0 -242
  85. data/lib/picky/indexing/bundle/memory.rb +0 -26
  86. data/lib/picky/indexing/bundle/redis.rb +0 -26
  87. data/lib/picky/query/combinations/base.rb +0 -74
  88. data/lib/picky/query/combinations/memory.rb +0 -52
  89. data/lib/picky/query/combinations/redis.rb +0 -90
  90. data/lib/picky/query.rb +0 -6
  91. data/lib/picky/tokenizers/base.rb +0 -231
  92. data/lib/picky/tokenizers/index.rb +0 -34
  93. data/lib/picky/tokenizers/query.rb +0 -61
  94. data/spec/lib/backend/files_spec.rb +0 -189
  95. data/spec/lib/backend/redis/list_hash_spec.rb +0 -40
  96. data/spec/lib/backend/redis/string_hash_spec.rb +0 -47
  97. data/spec/lib/backend/redis_spec.rb +0 -170
  98. data/spec/lib/indexed/bundle/redis_spec.rb +0 -41
  99. data/spec/lib/indexes/redis_spec.rb +0 -15
  100. data/spec/lib/indexing/bundle/base_spec.rb +0 -38
  101. data/spec/lib/indexing/bundle/memory_spec.rb +0 -287
  102. data/spec/lib/indexing/bundle/redis_spec.rb +0 -283
  103. data/spec/lib/query/combinations/memory_spec.rb +0 -158
  104. data/spec/lib/query/combinations/redis_spec.rb +0 -172
  105. data/spec/lib/tokenizers/index_spec.rb +0 -69
  106. data/spec/lib/tokenizers/query_spec.rb +0 -121
@@ -15,14 +15,14 @@ module Picky
15
15
  # will generate an example <tt>project_name/app/application.rb</tt> file for you
16
16
  # with some example code inside.
17
17
  #
18
- # == Indexes::Memory.new(name)
18
+ # == Index.new(name)
19
19
  #
20
- # Next, define where your data comes from, creating an <tt>Index</tt>. You use the <tt>Indexes::Memory.new</tt> method for that:
21
- # my_index = Indexes::Memory.new :some_index_name
20
+ # Next, define where your data comes from, creating an <tt>Index</tt>. You use the <tt>Index.new</tt> method for that:
21
+ # my_index = Index.new :some_index_name
22
22
  # You give the index a name (or identifier), and a source (see Sources), where its data comes from. Let's do that:
23
23
  # class MyGreatSearch < Application
24
24
  #
25
- # books = Indexes::Memory.new :books do
25
+ # books = Index.new :books do
26
26
  # source Sources::CSV.new(:title, :author, :isbn, file:'app/library.csv')
27
27
  # end
28
28
  #
@@ -31,7 +31,7 @@ module Picky
31
31
  #
32
32
  # That on itself won't do much good.
33
33
  #
34
- # Note that a Redis index is also available: Indexes::Redis.new.
34
+ # Note that a Redis index is also available: Index.new.
35
35
  #
36
36
  # == category(identifier, options = {})
37
37
  #
@@ -43,7 +43,7 @@ module Picky
43
43
  # Let's go ahead and define a category:
44
44
  # class MyGreatSearch < Application
45
45
  #
46
- # books = Indexes::Memory.new :books do
46
+ # books = Index.new :books do
47
47
  # source Sources::CSV.new(:title, :author, :isbn, file:'app/library.csv')
48
48
  # category :title
49
49
  # end
@@ -70,7 +70,7 @@ module Picky
70
70
  # In full glory:
71
71
  # class MyGreatSearch < Application
72
72
  #
73
- # books = Indexes::Memory.new :books do
73
+ # books = Index.new :books do
74
74
  # source Sources::CSV.new(:title, :author, :isbn, file:'app/library.csv')
75
75
  # category :title
76
76
  # end
@@ -134,7 +134,7 @@ module Picky
134
134
  # substitutes_characters_with: CharacterSubstituters::WestEuropean.new,
135
135
  # maximum_tokens: 4
136
136
  #
137
- # books = Indexes::Memory.new :books do
137
+ # books = Index.new :books do
138
138
  # source Sources::CSV.new(:title, :author, :isbn, file:'app/library.csv')
139
139
  # category :title,
140
140
  # qualifiers: [:t, :title, :titre],
@@ -163,14 +163,14 @@ module Picky
163
163
  # is used for indexing by default.
164
164
  #
165
165
  def indexing options = {}
166
- Tokenizers::Index.default = Tokenizers::Index.new(options)
166
+ Tokenizer.index_default = Tokenizer.new(options)
167
167
  end
168
168
 
169
169
  # Returns a configured tokenizer that
170
170
  # is used for querying by default.
171
171
  #
172
172
  def searching options = {}
173
- Tokenizers::Query.default = Tokenizers::Query.new(options)
173
+ Tokenizer.query_default = Tokenizer.new(options)
174
174
  end
175
175
 
176
176
  # Routes.
@@ -240,10 +240,10 @@ module Picky
240
240
  def to_stats
241
241
  <<-APP
242
242
  \033[1mIndexing (default)\033[m:
243
- #{Tokenizers::Index.default.indented_to_s}
243
+ #{Tokenizer.index_default.indented_to_s}
244
244
 
245
245
  \033[1mQuerying (default)\033[m:
246
- #{Tokenizers::Query.default.indented_to_s}
246
+ #{Tokenizer.query_default.indented_to_s}
247
247
 
248
248
  \033[1mIndexes\033[m:
249
249
  #{Indexes.to_s.indented_to_s}
@@ -0,0 +1,17 @@
1
+ module Picky
2
+
3
+ module Backends
4
+
5
+ class Backend
6
+
7
+ #
8
+ #
9
+ def to_s
10
+ "#{self.class}(#{[inverted, weights, similarity, configuration].join(', ')})"
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  # Handles all aspects of index files, such as dumping/loading.
6
6
  #
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  module File
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  module File
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  module File
6
6
 
@@ -0,0 +1,53 @@
1
+ module Picky
2
+
3
+ module Backends
4
+
5
+ class Memory < Backend
6
+
7
+ def create_inverted bundle
8
+ File::JSON.new bundle.index_path(:inverted)
9
+ end
10
+ def create_weights bundle
11
+ File::JSON.new bundle.index_path(:weights)
12
+ end
13
+ def create_similarity bundle
14
+ File::Marshal.new bundle.index_path(:similarity)
15
+ end
16
+ def create_configuration bundle
17
+ File::JSON.new bundle.index_path(:configuration)
18
+ end
19
+
20
+ # Returns the result ids for the allocation.
21
+ #
22
+ # Sorts the ids by size and & through them in the following order (sizes):
23
+ # 0. [100_000, 400, 30, 2]
24
+ # 1. [2, 30, 400, 100_000]
25
+ # 2. (100_000 & (400 & (30 & 2))) # => result
26
+ #
27
+ # Note: Uses a C-optimized intersection routine (in performant.c)
28
+ # for speed and memory efficiency.
29
+ #
30
+ # Note: In the memory based version we ignore the amount and offset hints.
31
+ # We cannot use the information to speed up the algorithm, unfortunately.
32
+ #
33
+ def ids combinations, _, _
34
+ return [] if combinations.empty?
35
+
36
+ # Get the ids for each combination.
37
+ #
38
+ id_arrays = combinations.inject([]) do |total, combination|
39
+ total << combination.ids
40
+ end
41
+
42
+ # Call the optimized C algorithm.
43
+ #
44
+ # Note: It orders the passed arrays by size.
45
+ #
46
+ Performant::Array.memory_efficient_intersect id_arrays
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  class Redis
6
6
 
@@ -13,34 +13,29 @@ module Picky
13
13
  #
14
14
  class Basic
15
15
 
16
- attr_reader :namespace, :backend
16
+ attr_reader :client, :namespace
17
17
 
18
18
  # An index cache takes a path, without file extension,
19
19
  # which will be provided by the subclasses.
20
20
  #
21
- def initialize namespace
21
+ def initialize client, namespace
22
+ @client = client
22
23
  @namespace = namespace
23
-
24
- # TODO Turn this inside out such that people can pass in
25
- # their own Redis instance.
26
- #
27
- # TODO Make the :db a real option.
28
- #
29
- @backend = ::Redis.new :db => 15
30
24
  end
31
25
 
32
- # Does nothing.
26
+ # Returns itself.
33
27
  #
34
28
  def load
35
- # Nothing.
29
+ self
36
30
  end
31
+
37
32
  # We do not use Redis to retrieve data.
38
33
  #
39
34
  def retrieve
40
35
  # Nothing.
41
36
  end
42
37
 
43
- # Redis does not backup.
38
+ # Redis doesn't do backup.
44
39
  #
45
40
  def backup
46
41
  # Nothing.
@@ -79,7 +74,7 @@ module Picky
79
74
  # DBSIZE KEYPATTERN, we are stuck with this.
80
75
  #
81
76
  def size
82
- backend.dbsize
77
+ client.dbsize
83
78
  end
84
79
 
85
80
  #
@@ -0,0 +1,26 @@
1
+ module Picky
2
+
3
+ module Backends
4
+
5
+ class Redis
6
+
7
+ class FloatHash < StringHash
8
+
9
+ # Get a single value.
10
+ #
11
+ # Internal API method for the index.
12
+ #
13
+ # Note: Works like the StringHash method, but
14
+ # returns a float corresponding to that string.
15
+ #
16
+ def [] key
17
+ super.to_f
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  class Redis
6
6
 
@@ -15,7 +15,7 @@ module Picky
15
15
  i = 0
16
16
  values.each do |value|
17
17
  i += 1
18
- backend.zadd redis_key, i, value
18
+ client.zadd redis_key, i, value
19
19
  end
20
20
  end
21
21
  end
@@ -27,21 +27,17 @@ module Picky
27
27
  #
28
28
  def clear
29
29
  redis_key = "#{namespace}:*"
30
- backend.keys(redis_key).each do |key|
31
- backend.del key
30
+ client.keys(redis_key).each do |key|
31
+ client.del key
32
32
  end
33
33
  end
34
34
 
35
35
  # Get a collection.
36
36
  #
37
- def collection key
38
- backend.zrange "#{namespace}:#{key}", 0, -1
39
- end
40
-
41
- # Get a single value.
37
+ # Internal API method for the index.
42
38
  #
43
- def member key
44
- raise "Can't retrieve single value :#{key} from a Redis ListHash. Use Indexes::Redis::StringHash."
39
+ def [] key
40
+ client.zrange "#{namespace}:#{key}", 0, -1
45
41
  end
46
42
 
47
43
  end
@@ -1,6 +1,6 @@
1
1
  module Picky
2
2
 
3
- module Backend
3
+ module Backends
4
4
 
5
5
  class Redis
6
6
 
@@ -13,26 +13,22 @@ module Picky
13
13
  def dump hash
14
14
  clear
15
15
  hash.each_pair do |key, value|
16
- backend.hset namespace, key, value
16
+ client.hset namespace, key, value
17
17
  end
18
18
  end
19
19
 
20
20
  # Clears the hash.
21
21
  #
22
22
  def clear
23
- backend.del namespace
24
- end
25
-
26
- # Get a collection.
27
- #
28
- def collection key
29
- raise "Can't retrieve collection for :#{key} from a StringHash. Use Indexes::Redis::ListHash."
23
+ client.del namespace
30
24
  end
31
25
 
32
26
  # Get a single value.
33
27
  #
34
- def member key
35
- backend.hget namespace, key
28
+ # Internal API method for the index.
29
+ #
30
+ def [] key
31
+ client.hget namespace, key
36
32
  end
37
33
 
38
34
  end
@@ -0,0 +1,87 @@
1
+ module Picky
2
+
3
+ module Backends
4
+
5
+ #
6
+ #
7
+ class Redis < Backend
8
+
9
+ attr_reader :client
10
+
11
+ def initialize options = {}
12
+ @client = options[:client] || ::Redis.new(:db => (options[:db] || 15))
13
+ end
14
+
15
+ def create_inverted bundle
16
+ Redis::ListHash.new client, "#{bundle.identifier}:inverted"
17
+ end
18
+ def create_weights bundle
19
+ Redis::FloatHash.new client, "#{bundle.identifier}:weights"
20
+ end
21
+ def create_similarity bundle
22
+ Redis::ListHash.new client, "#{bundle.identifier}:similarity"
23
+ end
24
+ def create_configuration bundle
25
+ Redis::StringHash.new client, "#{bundle.identifier}:configuration"
26
+ end
27
+
28
+ # Returns the result ids for the allocation.
29
+ #
30
+ # Developers wanting to program fast intersection
31
+ # routines, can do so analogue to this in their own
32
+ # backend implementations.
33
+ #
34
+ # Note: We use the amount and offset hints to speed Redis up.
35
+ #
36
+ def ids combinations, amount, offset
37
+ return [] if combinations.empty?
38
+
39
+ identifiers = combinations.inject([]) do |identifiers, combination|
40
+ identifiers << "#{combination.identifier}"
41
+ end
42
+
43
+ result_id = generate_intermediate_result_id
44
+
45
+ # Intersect and store.
46
+ #
47
+ client.zinterstore result_id, identifiers
48
+
49
+ # Get the stored result.
50
+ #
51
+ results = client.zrange result_id, offset, (offset + amount)
52
+
53
+ # Delete the stored result as it was only for temporary purposes.
54
+ #
55
+ # Note: I could also not delete it, but that would not be clean at all.
56
+ #
57
+ client.del result_id
58
+
59
+ results
60
+ end
61
+
62
+ # Generate a multiple host/process safe result id.
63
+ #
64
+ # Note: Generated when this class loads.
65
+ #
66
+ require 'socket'
67
+ def self.extract_host
68
+ @host ||= Socket.gethostname
69
+ end
70
+ def host
71
+ self.class.extract_host
72
+ end
73
+ extract_host
74
+ def pid
75
+ @pid ||= Process.pid
76
+ end
77
+ # Use the host and pid (generated lazily in child processes) for the result.
78
+ #
79
+ def generate_intermediate_result_id
80
+ :"#{host}:#{pid}:picky:result"
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ end
data/lib/picky/bundle.rb CHANGED
@@ -23,28 +23,37 @@ module Picky
23
23
  class Bundle
24
24
 
25
25
  attr_reader :name,
26
- :category
26
+ :category,
27
+ :backend
27
28
 
28
29
  attr_accessor :inverted,
29
30
  :weights,
30
31
  :similarity,
31
32
  :configuration,
33
+
34
+ :backend_inverted,
35
+ :backend_weights,
36
+ :backend_similarity,
37
+ :backend_configuration,
38
+
32
39
  :similarity_strategy
33
40
 
34
- delegate :clear, :to => :inverted
35
41
  delegate :[], :[]=, :to => :configuration
36
42
  delegate :index_directory, :to => :category
37
43
 
38
- def initialize name, category, similarity_strategy, options = {}
39
- @name = name
40
- @category = category
41
-
42
- @inverted = {}
43
- @weights = {}
44
- @similarity = {}
45
- @configuration = {} # A hash with config options.
46
-
44
+ def initialize name, category, backend, similarity_strategy, options = {}
45
+ @name = name
46
+ @category = category
47
47
  @similarity_strategy = similarity_strategy
48
+
49
+ # Extract specific indexes from backend.
50
+ #
51
+ # TODO Clean up all related.
52
+ #
53
+ @backend_inverted = backend.create_inverted self
54
+ @backend_weights = backend.create_weights self
55
+ @backend_similarity = backend.create_similarity self
56
+ @backend_configuration = backend.create_configuration self
48
57
  end
49
58
  def identifier
50
59
  "#{category.identifier}:#{name}"
@@ -79,6 +88,93 @@ module Picky
79
88
  ::File.join index_directory, "#{category.name}_#{name}_#{type}"
80
89
  end
81
90
 
91
+ # Copies the indexes to the "backup" directory.
92
+ #
93
+ def backup
94
+ @backend_inverted.backup if @backend_inverted.respond_to? :backup
95
+ @backend_weights.backup if @backend_weights.respond_to? :backup
96
+ @backend_similarity.backup if @backend_similarity.respond_to? :backup
97
+ @backend_configuration.backup if @backend_configuration.respond_to? :backup
98
+ end
99
+
100
+ # Restores the indexes from the "backup" directory.
101
+ #
102
+ def restore
103
+ @backend_inverted.restore if @backend_inverted.respond_to? :restore
104
+ @backend_weights.restore if @backend_weights.respond_to? :restore
105
+ @backend_similarity.restore if @backend_similarity.respond_to? :restore
106
+ @backend_configuration.restore if @backend_configuration.respond_to? :restore
107
+ end
108
+
109
+ # Delete all index files.
110
+ #
111
+ def delete
112
+ @backend_inverted.delete if @backend_inverted.respond_to? :delete
113
+ @backend_weights.delete if @backend_weights.respond_to? :delete
114
+ @backend_similarity.delete if @backend_similarity.respond_to? :delete
115
+ @backend_configuration.delete if @backend_configuration.respond_to? :delete
116
+ end
117
+
118
+ # Alerts the user if an index is missing.
119
+ #
120
+ def raise_unless_cache_exists
121
+ raise_unless_index_exists
122
+ raise_unless_similarity_exists
123
+ end
124
+ # Alerts the user if one of the necessary indexes
125
+ # (core, weights) is missing.
126
+ #
127
+ def raise_unless_index_exists
128
+ if partial_strategy.saved?
129
+ warn_if_index_small
130
+ raise_unless_index_ok
131
+ end
132
+ end
133
+ # Alerts the user if the similarity
134
+ # index is missing (given that it's used).
135
+ #
136
+ def raise_unless_similarity_exists
137
+ if similarity_strategy.saved?
138
+ warn_if_similarity_small
139
+ raise_unless_similarity_ok
140
+ end
141
+ end
142
+
143
+ # Outputs a warning for the given cache.
144
+ #
145
+ def warn_cache_small what
146
+ warn "Warning: #{what} cache for #{identifier} smaller than 16 bytes."
147
+ end
148
+ # Raises an appropriate error message for the given cache.
149
+ #
150
+ def raise_cache_missing what
151
+ raise "Error: The #{what} cache for #{identifier} is missing."
152
+ end
153
+
154
+ # Warns the user if the similarity index is small.
155
+ #
156
+ def warn_if_similarity_small
157
+ warn_cache_small :similarity if backend_similarity.respond_to?(:cache_small?) && backend_similarity.cache_small?
158
+ end
159
+ # Alerts the user if the similarity index is not there.
160
+ #
161
+ def raise_unless_similarity_ok
162
+ raise_cache_missing :similarity if backend_similarity.respond_to?(:cache_ok?) && !backend_similarity.cache_ok?
163
+ end
164
+
165
+ # Warns the user if the core or weights indexes are small.
166
+ #
167
+ def warn_if_index_small
168
+ warn_cache_small :inverted if backend_inverted.respond_to?(:cache_small?) && backend_inverted.cache_small?
169
+ warn_cache_small :weights if backend_weights.respond_to?(:cache_small?) && backend_weights.cache_small?
170
+ end
171
+ # Alerts the user if the core or weights indexes are not there.
172
+ #
173
+ def raise_unless_index_ok
174
+ raise_cache_missing :inverted if backend_inverted.respond_to?(:cache_ok?) && !backend_inverted.cache_ok?
175
+ raise_cache_missing :weights if backend_weights.respond_to?(:cache_ok?) && !backend_weights.cache_ok?
176
+ end
177
+
82
178
  def to_s
83
179
  "#{self.class}(#{identifier})"
84
180
  end
@@ -35,16 +35,16 @@ module Picky
35
35
  partial = options[:partial] || Generators::Partial::Default
36
36
  similarity = options[:similarity] || Generators::Similarity::Default
37
37
 
38
- @indexing_exact = index.indexing_bundle_class.new :exact, self, weights, Generators::Partial::None.new, similarity, options
39
- @indexing_partial = index.indexing_bundle_class.new :partial, self, weights, partial, Generators::Similarity::None.new, options
38
+ @indexing_exact = Indexing::Bundle.new :exact, self, index.backend, weights, Generators::Partial::None.new, similarity, options
39
+ @indexing_partial = Indexing::Bundle.new :partial, self, index.backend, weights, partial, Generators::Similarity::None.new, options
40
40
 
41
41
  # Indexed.
42
42
  #
43
- @indexed_exact = index.indexed_bundle_class.new :exact, self, similarity
43
+ @indexed_exact = Indexed::Bundle.new :exact, self, index.backend, similarity
44
44
  if partial.use_exact_for_partial?
45
45
  @indexed_partial = @indexed_exact
46
46
  else
47
- @indexed_partial = index.indexed_bundle_class.new :partial, self, similarity
47
+ @indexed_partial = Indexed::Bundle.new :partial, self, index.backend, similarity
48
48
  end
49
49
 
50
50
  # @exact = exact_lambda.call(@exact, @partial) if exact_lambda = options[:exact_lambda]
@@ -92,7 +92,7 @@ module Picky
92
92
  # Note: If you don't use it with the block, do not forget to close it.
93
93
  #
94
94
  def prepared_index_file &block
95
- @prepared_index_file ||= Backend::File::Text.new prepared_index_path
95
+ @prepared_index_file ||= Backends::File::Text.new prepared_index_path
96
96
  @prepared_index_file.open &block
97
97
  end
98
98
  # Creates the index directory including all necessary paths above it.