Skip to content

Commit

Permalink
add redis storage
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskite committed Sep 2, 2010
1 parent ada5cb4 commit 5d1e751
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 3 deletions.
5 changes: 5 additions & 0 deletions lib/anemone/storage.rb
Expand Up @@ -25,5 +25,10 @@ def self.MongoDB(mongo_db = nil, collection_name = 'pages')
self::MongoDB.new(mongo_db, collection_name)
end

def self.Redis(opts = {})
require 'anemone/storage/redis'
self::Redis.new(opts)
end

end
end
1 change: 1 addition & 0 deletions lib/anemone/storage/base.rb
Expand Up @@ -18,6 +18,7 @@ def initialize(adapter)
def [](key)
@adap[key]
rescue
puts key
raise RetrievalError, $!
end

Expand Down
90 changes: 90 additions & 0 deletions lib/anemone/storage/redis.rb
@@ -0,0 +1,90 @@
require 'redis'

module Anemone
module Storage
class Redis

MARSHAL_FIELDS = %w(links visited fetched)

def initialize(opts = {})
@redis = ::Redis.new(opts)
@key_prefix = opts[:key_prefix] || 'anemone'
keys.each { |key| delete(key) }
end

def [](key)
rkey = "#{@key_prefix}:pages:#{key.to_s}"
rget(rkey)
end

def []=(key, value)
rkey = "#{@key_prefix}:pages:#{key.to_s}"
hash = value.to_hash
MARSHAL_FIELDS.each do |field|
hash[field] = Marshal.dump(hash[field])
end
hash.each do |field, value|
@redis.hset(rkey, field, value)
end
end

def delete(key)
rkey = "#{@key_prefix}:pages:#{key.to_s}"
page = self[key]
@redis.del(rkey)
page
end

def each
rkeys = @redis.keys("#{@key_prefix}:pages:*")
rkeys.each do |rkey|
page = rget(rkey)
yield page.url.to_s, page
end
end

def merge!(hash)
hash.each { |key, value| self[key] = value }
self
end

def size
@redis.keys("#{@key_prefix}:pages:*").size
end

def keys
keys = []
self.each { |k, v| keys << k.to_s }
keys
end

def has_key?(key)
rkey = "#{@key_prefix}:pages:#{key.to_s}"
@redis.exists(rkey)
end

def close
@redis.quit
end

private

def load_value(hash)
MARSHAL_FIELDS.each do |field|
unless hash[field].nil? || hash[field] == ''
hash[field] = Marshal.load(hash[field])
end
end
Page.from_hash(hash)
end

def rget(rkey)
hash = @redis.hgetall(rkey)
if !!hash
load_value(hash)
end
end

end
end
end
14 changes: 13 additions & 1 deletion spec/page_store_spec.rb
@@ -1,5 +1,5 @@
require File.dirname(__FILE__) + '/spec_helper'
%w[pstore tokyo_cabinet mongodb].each { |file| require "anemone/storage/#{file}.rb" }
%w[pstore tokyo_cabinet mongodb redis].each { |file| require "anemone/storage/#{file}.rb" }

module Anemone
describe PageStore do
Expand Down Expand Up @@ -136,5 +136,17 @@ module Anemone
end
end

describe Storage::Redis do
it_should_behave_like "page storage"

before(:each) do
@opts = {:storage => @store = Storage.Redis}
end

after(:each) do
@store.close
end
end

end
end
23 changes: 21 additions & 2 deletions spec/storage_spec.rb
@@ -1,5 +1,5 @@
require File.dirname(__FILE__) + '/spec_helper'
%w[pstore tokyo_cabinet mongodb].each { |file| require "anemone/storage/#{file}.rb" }
%w[pstore tokyo_cabinet mongodb redis].each { |file| require "anemone/storage/#{file}.rb" }

module Anemone
describe Storage do
Expand Down Expand Up @@ -30,6 +30,13 @@ module Anemone
store.close
end

it "should have a class method to produce a Redis" do
Anemone::Storage.should respond_to(:Redis)
store = Anemone::Storage.Redis
store.should be_an_instance_of(Anemone::Storage::Redis)
store.close
end

module Storage
shared_examples_for "storage engine" do

Expand Down Expand Up @@ -138,7 +145,19 @@ module Storage
it_should_behave_like "storage engine"

before(:each) do
@opts = {:storage => @store = Storage.MongoDB}
@store = Storage.MongoDB
end

after(:each) do
@store.close
end
end

describe Storage::Redis do
it_should_behave_like "storage engine"

before(:each) do
@store = Storage.Redis
end

after(:each) do
Expand Down

0 comments on commit 5d1e751

Please sign in to comment.