Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add kyoto cabinet storage adapter

  • Loading branch information...
commit a081b092377194173aac0babb8788f8ac4849b34 1 parent 35473bb
@chriskite authored
View
1  .gitignore
@@ -2,3 +2,4 @@
Gemfile.lock
test.db
test.tch
+test.kch
View
4 Rakefile
@@ -14,8 +14,8 @@ end
task :default => :rspec
-require 'rake/rdoctask'
-Rake::RDocTask.new do |rdoc|
+require 'rdoc/task'
+RDoc::Task.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
rdoc.rdoc_dir = 'rdoc'
View
5 lib/anemone/storage.rb
@@ -18,6 +18,11 @@ def self.TokyoCabinet(file = 'anemone.tch')
self::TokyoCabinet.new(file)
end
+ def self.KyotoCabinet(file = 'anemone.tch')
+ require 'anemone/storage/kyoto_cabinet'
+ self::KyotoCabinet.new(file)
+ end
+
def self.MongoDB(mongo_db = nil, collection_name = 'pages')
require 'anemone/storage/mongodb'
mongo_db ||= Mongo::Connection.new.db('anemone')
View
72 lib/anemone/storage/kyoto_cabinet.rb
@@ -0,0 +1,72 @@
+begin
+ require 'kyotocabinet'
+rescue LoadError
+ puts $!
+ puts "You need the kyotocabinet-ruby gem to use Anemone::Storage::KyotoCabinet"
+ exit
+end
+
+require 'forwardable'
+
+module Anemone
+ module Storage
+ class KyotoCabinet
+ extend Forwardable
+
+ def_delegators :@db, :close, :size, :each
+
+ def initialize(file)
+ raise "KyotoCabinet filename must have .kch extension" if File.extname(file) != '.kch'
+ @db = ::KyotoCabinet::DB::new
+ @db.open(file, ::KyotoCabinet::DB::OWRITER | ::KyotoCabinet::DB::OCREATE)
+ @db.clear
+ end
+
+ def [](key)
+ if value = @db[key]
+ load_value(value)
+ end
+ end
+
+ def []=(key, value)
+ @db[key] = [Marshal.dump(value)].pack("m")
+ end
+
+ def each
+ @db.each do |k, v|
+ yield(k, load_value(v))
+ end
+ end
+
+ def has_key?(key)
+ # Kyoto Cabinet doesn't have a way to query whether a key exists, so hack it
+ keys = @db.match_prefix(key)
+ !!keys && keys.include?(key)
+ end
+
+ def keys
+ acc = []
+ @db.each_key { |key| acc << key.first }
+ acc
+ end
+
+ def delete(key)
+ value = self[key]
+ @db.delete(key)
+ value
+ end
+
+ def merge!(hash)
+ hash.each { |key, value| self[key] = value }
+ self
+ end
+
+ private
+
+ def load_value(value)
+ Marshal.load(value.unpack("m")[0])
+ end
+
+ end
+ end
+end
View
1  lib/anemone/storage/tokyo_cabinet.rb
@@ -1,6 +1,7 @@
begin
require 'tokyocabinet'
rescue LoadError
+ puts $!
puts "You need the tokyocabinet gem to use Anemone::Storage::TokyoCabinet"
exit
end
View
24 spec/storage_spec.rb
@@ -1,7 +1,7 @@
$:.unshift(File.dirname(__FILE__))
require 'spec_helper'
-%w[pstore tokyo_cabinet sqlite3 mongodb redis].each { |file| require "anemone/storage/#{file}.rb" }
+%w[pstore tokyo_cabinet kyoto_cabinet sqlite3 mongodb redis].each { |file| require "anemone/storage/#{file}.rb" }
module Anemone
describe Storage do
@@ -157,6 +157,28 @@ module Storage
end
end
+ describe KyotoCabinet do
+ it_should_behave_like "storage engine"
+
+ before(:each) do
+ @test_file = 'test.kch'
+ File.delete @test_file rescue nil
+ @store = Anemone::Storage.KyotoCabinet(@test_file)
+ end
+
+ after(:each) do
+ @store.close
+ end
+
+ after(:all) do
+ File.delete @test_file rescue nil
+ end
+
+ it "should raise an error if supplied with a file extension other than .kch" do
+ lambda { Anemone::Storage.KyotoCabinet('test.tmp') }.should raise_error(RuntimeError)
+ end
+ end
+
describe SQLite3 do
it_should_behave_like "storage engine"

0 comments on commit a081b09

Please sign in to comment.
Something went wrong with that request. Please try again.