Permalink
Browse files

+ backends experimental rewrite

  • Loading branch information...
1 parent 0ad356f commit 2fc80c80149bd5e2dde154e2fc25638913bf1226 @floere committed Nov 25, 2011
@@ -46,6 +46,13 @@ def create_configuration bundle
extract_lambda_or(configuration, bundle, client) ||
String.new(client, "#{bundle.identifier}:configuration", immediate: immediate)
end
+ # Returns an object that on #initial, #load returns an object that responds to:
+ # [id] # => [:sym1, :sym2]
+ #
+ def create_realtime bundle
+ extract_lambda_or(similarity, bundle) ||
+ List.new(client, "#{bundle.identifier}:realtime", immediate: immediate)
+ end
# Does the Redis version already include
# scripting support?
@@ -89,6 +96,9 @@ def redis_version
#
# Note: We use the amount and offset hints to speed Redis up.
#
+ # TODO What if it hasn't been dumped?
+ # Move this method to the actual backends?
+ #
def ids combinations, amount, offset
# Just checked once on the first call.
#
@@ -6,6 +6,24 @@ class Redis
class List < Basic
+ # Clear the index for this list.
+ #
+ # Note: Perhaps we can use a server only command.
+ # This is not the optimal way to do it.
+ #
+ def clear
+ redis_key = "#{namespace}:*"
+ client.keys(redis_key).each do |key|
+ client.del key
+ end
+ end
+
+ # Deletes the list for the key.
+ #
+ def delete key
+ client.del key
+ end
+
# Writes the hash into Redis.
#
def dump hash
@@ -22,18 +40,6 @@ def dump hash
end
end
- # Clear the index for this list.
- #
- # Note: Perhaps we can use a server only command.
- # This is not the optimal way to do it.
- #
- def clear
- redis_key = "#{namespace}:*"
- client.keys(redis_key).each do |key|
- client.del key
- end
- end
-
# Get a collection.
#
# Internal API method for the index.
@@ -53,6 +59,7 @@ def []= key, values
i += 1
client.zadd redis_key, i, value
end
+ self[key] # TODO Performance?
end
def realtime_extend array, key
@@ -63,21 +70,28 @@ def realtime_extend array, key
module Realtime
attr_accessor :db, :key
+
+ # TODO Current implementation does not keep order.
+ #
def << value
super value
- db[key] = self
+ db.client.zadd "#{db.namespace}:#{key}", 0, value
+ db[key]
end
+ # TODO Current implementation does not keep order.
+ #
def unshift value
super value
- db[key] = self
+ db.client.zadd "#{db.namespace}:#{key}", 0, value
+ db[key]
end
- end
- # Deletes the list.
- #
- def delete key
- p [:DELETE_LIST]
+ def delete value
+ result = super value
+ db.client.zrem "#{db.namespace}:#{key}", value # TODO if super(value) ?
+ result
+ end
end
end
@@ -6,6 +6,18 @@ class Redis
class String < Basic
+ # Clears the hash.
+ #
+ def clear
+ client.del namespace
+ end
+
+ # Deletes the single value.
+ #
+ def delete key
+ client.hdel namespace, key
+ end
+
# Writes the hash into Redis.
#
# Note: We could use multi, but it did not help.
@@ -19,12 +31,6 @@ def dump hash
end
end
- # Clears the hash.
- #
- def clear
- client.del namespace
- end
-
# Get a single value.
#
# Internal API method for the index.
@@ -39,12 +45,6 @@ def []= key, value
client.hset namespace, key, value
end
- # Deletes the single value.
- #
- def delete key
- p [:DELETE_VALUE]
- end
-
end
end
@@ -43,16 +43,21 @@ module Realtime
def << value
super value
db[key] = self
+ self
end
def unshift value
super value
db[key] = self
+ self
end
def delete value
value = super value
- db[key] = self if value
+ if value
+ db[key] = self
+ value
+ end
end
end
@@ -127,7 +127,10 @@ def empty_realtime
def similar text
code = similarity_strategy.encoded text
similar_codes = code && @similarity[code]
- similar_codes.delete text if similar_codes
+ if similar_codes
+ similar_codes = similar_codes.dup # TODO
+ similar_codes.delete text
+ end
similar_codes || []
end
@@ -20,6 +20,9 @@ class Bundle
#
# Returns a (potentially empty) array of ids.
#
+ # TODO Empty string ok, or does it need to be from the backend?
+ # Should the backend always return an empty array? (Probably no)
+ #
def ids sym_or_string
@inverted[sym_or_string] || []
end
@@ -42,7 +42,10 @@ def add id, str_or_sym, where = :unshift
ids.send where, id
else
str_or_syms << str_or_sym
- ids = @inverted[str_or_sym] || (@inverted[str_or_sym] = []) # ensures that we get an extended Array
+
+ # TODO Introduce a new method?
+ #
+ ids = @inverted[str_or_sym] || (@inverted[str_or_sym] = []) # Ensures that we get an extended Array
ids.send where, id
end
@@ -65,7 +68,7 @@ def add id, str_or_sym, where = :unshift
#
def add_similarity str_or_sym, where = :unshift
if encoded = self.similarity_strategy.encoded(str_or_sym)
- similarity = @similarity[encoded] || (@similarity[encoded] = []) # ensures that we get an extended Array
+ similarity = @similarity[encoded] || (@similarity[encoded] = []) # Ensures that we get an extended Array
if similarity.include? str_or_sym
similarity.delete str_or_sym # Not completely correct, as others will also be affected, but meh.
similarity.send where, str_or_sym #
@@ -18,7 +18,7 @@ class Allocation # :nodoc:all
def initialize index, combinations
@combinations = combinations
@result_identifier = index.result_identifier # TODO Make cleverer.
- @backend = index.backend # TODO Make cleverer.
+ @backend = index.backend # TODO Make cleverer. Use inverted?
end
def hash
@@ -132,7 +132,7 @@ def similarity bundle = nil
# (We avoid a StopIteration exception. Which of both is less evil?)
#
def generate_similarity_for bundle
- bundle.similar(@text).dup || []
+ bundle.similar(@text) || []
end
# Splits text into a qualifier and text.
@@ -0,0 +1,96 @@
+# encoding: utf-8
+#
+require 'spec_helper'
+
+# Describes a Picky index that uses the SQLite backend
+# for data storage.
+#
+describe Picky::Backends::Memory do
+
+ class Book
+ attr_reader :id, :title, :author
+ def initialize id, title, author
+ @id, @title, @author = id, title, author
+ end
+ end
+
+ attr_reader :data, :books
+
+ let(:data) do
+ Picky::Index.new(:books) do
+ key_format :to_s # TODO Also make to_i work.
+ source []
+ category :title, partial: Picky::Partial::Postfix.new(from: 1)
+ category :author, similarity: Picky::Generators::Similarity::DoubleMetaphone.new(3)
+ end
+ end
+ let(:books) { Picky::Search.new data }
+
+ its = ->(*) do
+ it 'searching for it' do
+ books.search('title').ids.should == ['1']
+ end
+ it 'searching for it using multiple words' do
+ books.search('title author').ids.should == ['1']
+ end
+ it 'searching for it using partial' do
+ books.search('tit').ids.should == ['1']
+ end
+ it 'searching for it using similarity' do
+ books.search('aothor~').ids.should == ['1']
+ end
+ it 'handles removing' do
+ data.remove 1
+
+ books.search('title').ids.should == []
+ end
+ it 'handles removing with more than one entry' do
+ data.add Book.new(2, 'title', 'author')
+
+ books.search('title').ids.should == ['2', '1'] # TODO Should be ['2', '1']
+
+ data.remove '1'
+
+ books.search('title').ids.should == ['2']
+ end
+ it 'handles removing with three entries' do
+ data.add Book.new(2, 'title', 'author')
+ data.add Book.new(3, 'title', 'author')
+
+ books.search('title').ids.should == ['3', '2', '1'] # TODO Should be ['3', '2', '1']
+
+ data.remove '1'
+
+ books.search('title').ids.should == ['3', '2']
+ end
+ it 'handles replacing' do
+ data.replace Book.new(1, 'toitle', 'oithor')
+
+ books.search('title').ids.should == []
+ books.search('toitle').ids.should == ['1']
+ end
+ it 'handles clearing' do
+ data.clear
+
+ books.search('title').ids.should == []
+ end
+ it 'handles dumping and loading' do
+ data.dump
+ data.load
+
+ books.search('title').ids.should == ['1']
+ end
+ end
+
+ context 'immediately indexing backend (no dump needed)' do
+ before(:each) do
+ data.backend described_class.new
+ data.clear
+
+ data.add Book.new(1, 'title', 'author')
+ end
+
+ instance_eval &its
+ end
+
+end
@@ -18,6 +18,7 @@ def initialize id, title, author
let(:data) do
Picky::Index.new(:books) do
+ key_format :to_s # TODO Also make to_i work.
source []
category :title, partial: Picky::Partial::Postfix.new(from: 1)
category :author, similarity: Picky::Generators::Similarity::DoubleMetaphone.new(3)
@@ -44,14 +45,24 @@ def initialize id, title, author
books.search('title').ids.should == []
end
it 'handles removing with more than one entry' do
- data.add Book.new(2, 'newtitle', 'newauthor')
+ data.add Book.new(2, 'title', 'author')
- books.search('title').ids.should == ['2', '1']
+ books.search('title').ids.should == ['2', '1'] # TODO Should be ['2', '1']
data.remove '1'
books.search('title').ids.should == ['2']
end
+ it 'handles removing with three entries' do
+ data.add Book.new(2, 'title', 'author')
+ data.add Book.new(3, 'title', 'author')
+
+ books.search('title').ids.should == ['3', '2', '1'] # TODO Should be ['3', '2', '1']
+
+ data.remove '1'
+
+ books.search('title').ids.should == ['3', '2']
+ end
it 'handles replacing' do
data.replace Book.new(1, 'toitle', 'oithor')
@@ -50,6 +50,16 @@ def initialize id, title, author
books.search('title').ids.should == [2]
end
+ it 'handles removing with three entries' do
+ data.add Book.new(2, 'title', 'author')
+ data.add Book.new(3, 'title', 'author')
+
+ books.search('title').ids.should == [3, 2, 1]
+
+ data.remove 1
+
+ books.search('title').ids.should == [3, 2]
+ end
it 'handles replacing' do
data.replace Book.new(1, 'toitle', 'oithor')
Oops, something went wrong.

0 comments on commit 2fc80c8

Please sign in to comment.