jruby-memcached 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/benchmark.rb +39 -26
- data/lib/memcached.rb +1 -129
- data/lib/memcached/version.rb +1 -1
- data/pom.xml +1 -1
- data/spec/memcached_spec.rb +3 -27
- data/src/main/java/com/openfeint/memcached/MarshalTranscoder.java +62 -0
- data/src/main/java/com/openfeint/memcached/MarshalZlibTranscoder.java +97 -0
- data/src/main/java/com/openfeint/memcached/Memcached.java +325 -0
- data/src/main/java/com/openfeint/memcached/MemcachedLibrary.java +52 -0
- data/target/spymemcached-ext-0.0.1.jar +0 -0
- metadata +7 -5
- data/src/main/java/net/spy/memcached/ReturnData.java +0 -20
- data/src/main/java/net/spy/memcached/transcoders/SimpleTranscoder.java +0 -53
data/Gemfile.lock
CHANGED
data/benchmark.rb
CHANGED
@@ -2,15 +2,17 @@ require 'benchmark'
|
|
2
2
|
|
3
3
|
JRUBY = defined?(JRUBY_VERSION)
|
4
4
|
|
5
|
+
require 'rubygems'
|
5
6
|
if JRUBY
|
6
7
|
require 'lib/memcached'
|
8
|
+
require 'jruby-spymemcached'
|
7
9
|
else
|
8
10
|
require 'memcached'
|
9
11
|
end
|
10
|
-
require 'rubygems'
|
11
12
|
require 'dalli'
|
12
13
|
|
13
14
|
memcached = Memcached.new(['localhost:11211'])
|
15
|
+
spymemcached = Spymemcached.new(['localhost:11211']) if JRUBY
|
14
16
|
dalli = Dalli::Client.new(['localhost:11211'])
|
15
17
|
|
16
18
|
3.to_i.times {
|
@@ -22,6 +24,12 @@ dalli = Dalli::Client.new(['localhost:11211'])
|
|
22
24
|
bm.report("jruby-memcached get") {
|
23
25
|
100_000.times { memcached.get('foo') }
|
24
26
|
}
|
27
|
+
bm.report("jruby-spymemcached set") {
|
28
|
+
100_000.times { spymemcached.set('foo', 'bar') }
|
29
|
+
}
|
30
|
+
bm.report("jruby-spymemcached get") {
|
31
|
+
100_000.times { spymemcached.get('foo') }
|
32
|
+
}
|
25
33
|
else
|
26
34
|
bm.report("memcached set") {
|
27
35
|
100_000.times { memcached.set('foo', 'bar') }
|
@@ -44,29 +52,46 @@ dalli = Dalli::Client.new(['localhost:11211'])
|
|
44
52
|
}
|
45
53
|
}
|
46
54
|
|
47
|
-
|
55
|
+
if JRUBY
|
56
|
+
memcached.shutdown
|
57
|
+
spymemcached.shutdown
|
58
|
+
end
|
48
59
|
dalli.close
|
49
60
|
|
50
|
-
|
51
|
-
#
|
61
|
+
# I run benchmark for each client 3 times, but only list the last result for each.
|
62
|
+
#
|
63
|
+
# MBP 2.8G i7 jruby-memcached 0.3.0
|
52
64
|
#
|
53
65
|
# ruby-1.9.3-p194
|
54
66
|
# ruby benchmark.rb
|
55
67
|
# user system total real
|
56
|
-
# memcached set 1.110000 1.010000 2.120000 ( 4.578121)
|
57
|
-
# memcached get 0.940000 0.960000 1.900000 ( 4.013941)
|
58
|
-
# user system total real
|
59
|
-
# memcached set 1.100000 1.010000 2.110000 ( 4.557462)
|
60
|
-
# memcached get 0.930000 0.950000 1.880000 ( 3.995192)
|
61
|
-
# user system total real
|
62
68
|
# memcached set 1.110000 1.020000 2.130000 ( 4.592509)
|
63
69
|
# memcached get 0.970000 1.000000 1.970000 ( 4.172170)
|
64
70
|
# user system total real
|
65
|
-
# dalli set 8.
|
66
|
-
# dalli get 8.
|
71
|
+
# dalli set 8.360000 1.650000 10.010000 ( 10.193101)
|
72
|
+
# dalli get 8.040000 1.670000 9.710000 ( 9.828392)
|
73
|
+
#
|
74
|
+
# jruby-1.6.7.2
|
75
|
+
# jruby --server -Ilib -S benchmark.rb
|
76
|
+
# user system total real
|
77
|
+
# jruby-memcached set 5.842000 0.000000 5.842000 ( 5.842000)
|
78
|
+
# jruby-memcached get 5.561000 0.000000 5.561000 ( 5.561000)
|
79
|
+
# user system total real
|
80
|
+
# jruby-spymemcached set 5.919000 0.000000 5.919000 ( 5.919000)
|
81
|
+
# jruby-spymemcached get 5.615000 0.000000 5.615000 ( 5.615000)
|
82
|
+
# user system total real
|
83
|
+
# dalli set 10.132000 0.000000 10.132000 ( 10.132000)
|
84
|
+
# dalli get 10.600000 0.000000 10.600000 ( 10.600000)
|
85
|
+
#
|
86
|
+
##############################################################################
|
87
|
+
#
|
88
|
+
# MBP 2.8G i7 jruby-memcached 0.1.0
|
89
|
+
#
|
90
|
+
# ruby-1.9.3-p194
|
91
|
+
# ruby benchmark.rb
|
67
92
|
# user system total real
|
68
|
-
#
|
69
|
-
#
|
93
|
+
# memcached set 1.110000 1.020000 2.130000 ( 4.592509)
|
94
|
+
# memcached get 0.970000 1.000000 1.970000 ( 4.172170)
|
70
95
|
# user system total real
|
71
96
|
# dalli set 8.330000 1.560000 9.890000 ( 10.094499)
|
72
97
|
# dalli get 8.530000 1.680000 10.210000 ( 10.331083)
|
@@ -74,20 +99,8 @@ dalli.close
|
|
74
99
|
# jruby-1.6.7.2
|
75
100
|
# jruby --server -Ilib -S benchmark.rb
|
76
101
|
# user system total real
|
77
|
-
# jruby-memcached set 8.745000 0.000000 8.745000 ( 8.745000)
|
78
|
-
# jruby-memcached get 8.260000 0.000000 8.260000 ( 8.260000)
|
79
|
-
# user system total real
|
80
|
-
# jruby-memcached set 6.911000 0.000000 6.911000 ( 6.911000)
|
81
|
-
# jruby-memcached get 6.895000 0.000000 6.895000 ( 6.895000)
|
82
|
-
# user system total real
|
83
102
|
# jruby-memcached set 6.902000 0.000000 6.902000 ( 6.902000)
|
84
103
|
# jruby-memcached get 6.845000 0.000000 6.845000 ( 6.845000)
|
85
104
|
# user system total real
|
86
|
-
# dalli set 15.233000 0.000000 15.233000 ( 15.234000)
|
87
|
-
# dalli get 13.991000 0.000000 13.991000 ( 13.992000)
|
88
|
-
# user system total real
|
89
|
-
# dalli set 12.936000 0.000000 12.936000 ( 12.936000)
|
90
|
-
# dalli get 13.585000 0.000000 13.585000 ( 13.585000)
|
91
|
-
# user system total real
|
92
105
|
# dalli set 13.251000 0.000000 13.251000 ( 13.251000)
|
93
106
|
# dalli get 13.536000 0.000000 13.536000 ( 13.536000)
|
data/lib/memcached.rb
CHANGED
@@ -1,133 +1,5 @@
|
|
1
1
|
require 'java'
|
2
2
|
require 'memcached/version'
|
3
|
-
require 'memcached/exceptions'
|
4
3
|
require File.join(File.dirname(__FILE__), '../target/spymemcached-ext-0.0.1.jar')
|
5
4
|
|
6
|
-
|
7
|
-
java_import 'net.spy.memcached.ConnectionFactoryBuilder'
|
8
|
-
java_import 'net.spy.memcached.ConnectionFactoryBuilder$Locator'
|
9
|
-
java_import 'net.spy.memcached.ConnectionFactoryBuilder$Protocol'
|
10
|
-
java_import 'net.spy.memcached.DefaultHashAlgorithm'
|
11
|
-
java_import 'net.spy.memcached.transcoders.SimpleTranscoder'
|
12
|
-
java_import 'net.spy.memcached.AddrUtil'
|
13
|
-
|
14
|
-
class Memcached
|
15
|
-
|
16
|
-
FLAGS = 0x0
|
17
|
-
DEFAULTS = {
|
18
|
-
:binary_protocol => false,
|
19
|
-
:default_ttl => 604800,
|
20
|
-
:distribution => :consistent_ketama,
|
21
|
-
:exception_retry_limit => 5,
|
22
|
-
:hash => :fnv1_32,
|
23
|
-
}
|
24
|
-
|
25
|
-
attr_reader :options
|
26
|
-
attr_reader :default_ttl
|
27
|
-
|
28
|
-
def initialize(addresses, options={})
|
29
|
-
@options = DEFAULTS.merge(options)
|
30
|
-
@default_ttl = @options[:default_ttl]
|
31
|
-
|
32
|
-
builder = ConnectionFactoryBuilder.new
|
33
|
-
|
34
|
-
@options[:distribution] = :consistent if @options[:distribution] == :ketama || @options[:distribution] == :consistent_ketama
|
35
|
-
unless [:array_mod, :consistent].include? @options[:distribution]
|
36
|
-
raise Memcached::NotSupport.new("#{@options[:distribution]} distribution algorithm doesn't support yet.")
|
37
|
-
end
|
38
|
-
distribution_algorithm = Locator.const_get @options[:distribution].to_s.upcase
|
39
|
-
builder.setLocatorType(distribution_algorithm)
|
40
|
-
|
41
|
-
if @options[:binary_protocol]
|
42
|
-
builder.setProtocol(Protocol::BINARY)
|
43
|
-
end
|
44
|
-
|
45
|
-
unless [:native, :crc, :fnv1_64, :fnv1a_64, :fnv1_32, :fnv1a_32, :ketama].include? @options[:hash]
|
46
|
-
raise Memcached::NotSupport.new("#{@options[:hash]} hash algorithm doesn't support yet.")
|
47
|
-
end
|
48
|
-
hash_algorithm = DefaultHashAlgorithm.const_get "#{@options[:hash]}_HASH".upcase
|
49
|
-
builder.setHashAlg hash_algorithm
|
50
|
-
|
51
|
-
@client = MemcachedClient.new builder.build, AddrUtil.getAddresses(Array(addresses).join(' '))
|
52
|
-
|
53
|
-
@simple_transcoder = SimpleTranscoder.new
|
54
|
-
end
|
55
|
-
|
56
|
-
def set(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS)
|
57
|
-
with_retry do
|
58
|
-
value = encode(value, marshal, flags)
|
59
|
-
@simple_transcoder.setFlags(flags)
|
60
|
-
@client.set(key, ttl, value.to_java_bytes, @simple_transcoder).get
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def add(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS)
|
65
|
-
with_retry do
|
66
|
-
value = encode(value, marshal, flags)
|
67
|
-
@simple_transcoder.setFlags(flags)
|
68
|
-
if @client.add(key, ttl, value.to_java_bytes, @simple_transcoder).get === false
|
69
|
-
raise Memcached::NotStored
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def replace(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS)
|
75
|
-
with_retry do
|
76
|
-
value = encode(value, marshal, flags)
|
77
|
-
@simple_transcoder.setFlags(flags)
|
78
|
-
if @client.replace(key, ttl, value.to_java_bytes, @simple_transcoder).get === false
|
79
|
-
raise Memcached::NotStored
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def delete(key)
|
85
|
-
with_retry do
|
86
|
-
raise Memcached::NotFound if @client.delete(key).get === false
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def get(key, marshal=true)
|
91
|
-
with_retry do
|
92
|
-
ret = @client.get(key, @simple_transcoder)
|
93
|
-
raise Memcached::NotFound if ret.nil?
|
94
|
-
flags, data = ret.flags, ret.data
|
95
|
-
value = String.from_java_bytes data
|
96
|
-
value = decode(value, marshal, flags)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def flush
|
101
|
-
@client.flush.get
|
102
|
-
end
|
103
|
-
|
104
|
-
def servers
|
105
|
-
@client.available_servers.map { |address| address.to_s.split("/").last }
|
106
|
-
end
|
107
|
-
|
108
|
-
def close
|
109
|
-
@client.shutdown
|
110
|
-
end
|
111
|
-
|
112
|
-
alias_method :quit, :close
|
113
|
-
|
114
|
-
private
|
115
|
-
def with_retry
|
116
|
-
begin
|
117
|
-
yield
|
118
|
-
rescue
|
119
|
-
tries ||= 0
|
120
|
-
raise unless tries < options[:exception_retry_limit]
|
121
|
-
tries += 1
|
122
|
-
retry
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def encode(value, marshal, flags)
|
127
|
-
marshal ? Marshal.dump(value) : value
|
128
|
-
end
|
129
|
-
|
130
|
-
def decode(value, marshal, flags)
|
131
|
-
marshal ? Marshal.load(value) : value
|
132
|
-
end
|
133
|
-
end
|
5
|
+
com.openfeint.memcached.MemcachedLibrary.new.load(JRuby.runtime, false)
|
data/lib/memcached/version.rb
CHANGED
data/pom.xml
CHANGED
data/spec/memcached_spec.rb
CHANGED
@@ -1,30 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
com.openfeint.memcached.MemcachedLibrary.new.load(JRuby.runtime, false)
|
3
4
|
describe Memcached do
|
4
5
|
context "localhost" do
|
5
|
-
before(:all) { @memcached = Memcached.new("127.0.0.1:11211") }
|
6
|
-
after(:all) { @memcached.
|
6
|
+
before(:all) { @memcached = Memcached.new(["127.0.0.1:11211"]) }
|
7
|
+
after(:all) { @memcached.shutdown }
|
7
8
|
|
8
9
|
it "should get all servers" do
|
9
10
|
@memcached.servers.should == ["127.0.0.1:11211"]
|
10
11
|
end
|
11
12
|
|
12
13
|
context "initialize" do
|
13
|
-
before(:all) do
|
14
|
-
@memcached_with_options = Memcached.new("127.0.0.1:11211", :hash => :fnv1_32,
|
15
|
-
:distribution => :ketama,
|
16
|
-
:default_ttl => 900)
|
17
|
-
end
|
18
|
-
after(:all) { @memcached_with_options.close }
|
19
|
-
|
20
|
-
it "should with option hash" do
|
21
|
-
@memcached_with_options.options[:hash].should == :fnv1_32
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should with option distribution" do
|
25
|
-
@memcached_with_options.options[:distribution].should == :consistent
|
26
|
-
end
|
27
|
-
|
28
14
|
it "should raise error with unsupported option hash" do
|
29
15
|
lambda { Memcached.new("127.0.0.1:11211", :hash => :unknown) }.should raise_error(Memcached::NotSupport)
|
30
16
|
end
|
@@ -32,10 +18,6 @@ describe Memcached do
|
|
32
18
|
it "should raise error with unsupported option distribution" do
|
33
19
|
lambda { Memcached.new("127.0.0.1:11211", :distribution => :unknown) }.should raise_error(Memcached::NotSupport)
|
34
20
|
end
|
35
|
-
|
36
|
-
it "should get default ttl" do
|
37
|
-
@memcached_with_options.default_ttl.should == 900
|
38
|
-
end
|
39
21
|
end
|
40
22
|
|
41
23
|
context "set/get" do
|
@@ -69,12 +51,6 @@ describe Memcached do
|
|
69
51
|
sleep 1
|
70
52
|
lambda { @memcached.get("key") }.should raise_error(Memcached::NotFound)
|
71
53
|
end
|
72
|
-
|
73
|
-
it "should retry when set failure" do
|
74
|
-
Java::NetSpyMemcached::MemcachedClient.any_instance.stubs(:set).raises(Memcached::NotStored)
|
75
|
-
Java::NetSpyMemcachedTranscoders::SimpleTranscoder.any_instance.expects(:setFlags).times(6)
|
76
|
-
lambda { @memcached.set "key", "value" }.should raise_error(Memcached::NotStored)
|
77
|
-
end
|
78
54
|
end
|
79
55
|
|
80
56
|
context "add" do
|
@@ -0,0 +1,62 @@
|
|
1
|
+
package com.openfeint.memcached;
|
2
|
+
|
3
|
+
import java.io.ByteArrayInputStream;
|
4
|
+
import java.io.ByteArrayOutputStream;
|
5
|
+
import java.io.IOException;
|
6
|
+
import net.spy.memcached.CachedData;
|
7
|
+
import net.spy.memcached.transcoders.Transcoder;
|
8
|
+
import org.jruby.Ruby;
|
9
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
10
|
+
import org.jruby.runtime.marshal.MarshalStream;
|
11
|
+
import org.jruby.runtime.marshal.UnmarshalStream;
|
12
|
+
|
13
|
+
/**
|
14
|
+
*
|
15
|
+
* MarshalTranscoder does marshaling and unmarshaling.
|
16
|
+
*
|
17
|
+
*/
|
18
|
+
public class MarshalTranscoder implements Transcoder<IRubyObject> {
|
19
|
+
private Ruby ruby;
|
20
|
+
private int flags;
|
21
|
+
|
22
|
+
public MarshalTranscoder(Ruby ruby) {
|
23
|
+
this(ruby, 0);
|
24
|
+
}
|
25
|
+
|
26
|
+
public MarshalTranscoder(Ruby ruby, int flags) {
|
27
|
+
this.ruby = ruby;
|
28
|
+
this.flags = flags;
|
29
|
+
}
|
30
|
+
|
31
|
+
public boolean asyncDecode(CachedData d) {
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
|
35
|
+
public CachedData encode(IRubyObject o) {
|
36
|
+
try {
|
37
|
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
38
|
+
MarshalStream marshal = new MarshalStream(ruby, baos, Integer.MAX_VALUE);
|
39
|
+
marshal.dumpObject(o);
|
40
|
+
byte[] bytes = baos.toByteArray();
|
41
|
+
return new CachedData(getFlags(), bytes, bytes.length);
|
42
|
+
} catch (IOException ioe) {
|
43
|
+
throw ruby.newIOErrorFromException(ioe);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
public IRubyObject decode(CachedData d) {
|
48
|
+
try {
|
49
|
+
return new UnmarshalStream(ruby, new ByteArrayInputStream(d.getData()), null, false, false).unmarshalObject();
|
50
|
+
} catch (IOException ioe) {
|
51
|
+
throw ruby.newIOErrorFromException(ioe);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
public int getMaxSize() {
|
56
|
+
return CachedData.MAX_SIZE;
|
57
|
+
}
|
58
|
+
|
59
|
+
public int getFlags() {
|
60
|
+
return flags;
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
package com.openfeint.memcached;
|
2
|
+
|
3
|
+
import java.io.ByteArrayInputStream;
|
4
|
+
import java.io.ByteArrayOutputStream;
|
5
|
+
import java.io.ObjectInputStream;
|
6
|
+
import java.io.ObjectOutputStream;
|
7
|
+
import java.io.IOException;
|
8
|
+
import net.spy.memcached.CachedData;
|
9
|
+
import net.spy.memcached.transcoders.Transcoder;
|
10
|
+
import org.jruby.Ruby;
|
11
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
12
|
+
import org.jruby.runtime.marshal.MarshalStream;
|
13
|
+
import org.jruby.runtime.marshal.UnmarshalStream;
|
14
|
+
import org.jruby.util.ByteList;
|
15
|
+
import com.jcraft.jzlib.ZOutputStream;
|
16
|
+
import com.jcraft.jzlib.ZInputStream;
|
17
|
+
import com.jcraft.jzlib.JZlib;
|
18
|
+
|
19
|
+
/**
|
20
|
+
*
|
21
|
+
* MarshalZlibTranscoder do marshaling/unmarshaling and compressing/decompressing with zlib.
|
22
|
+
*
|
23
|
+
*/
|
24
|
+
public class MarshalZlibTranscoder implements Transcoder<IRubyObject> {
|
25
|
+
private Ruby ruby;
|
26
|
+
private int flags;
|
27
|
+
|
28
|
+
public MarshalZlibTranscoder(Ruby ruby) {
|
29
|
+
this(ruby, 1);
|
30
|
+
}
|
31
|
+
|
32
|
+
public MarshalZlibTranscoder(Ruby ruby, int flags) {
|
33
|
+
this.ruby = ruby;
|
34
|
+
this.flags = flags;
|
35
|
+
}
|
36
|
+
|
37
|
+
public boolean asyncDecode(CachedData d) {
|
38
|
+
return false;
|
39
|
+
}
|
40
|
+
|
41
|
+
public CachedData encode(IRubyObject o) {
|
42
|
+
try {
|
43
|
+
ByteArrayOutputStream out1 = new ByteArrayOutputStream();
|
44
|
+
MarshalStream marshal = new MarshalStream(ruby, out1, Integer.MAX_VALUE);
|
45
|
+
marshal.dumpObject(o);
|
46
|
+
|
47
|
+
byte[] bytes;
|
48
|
+
if (flags == 1) {
|
49
|
+
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
|
50
|
+
ZOutputStream zout = new ZOutputStream(out2, JZlib.Z_DEFAULT_COMPRESSION);
|
51
|
+
zout.write(out1.toByteArray());
|
52
|
+
zout.close();
|
53
|
+
bytes = out2.toByteArray();
|
54
|
+
} else {
|
55
|
+
bytes = out1.toByteArray();
|
56
|
+
}
|
57
|
+
|
58
|
+
return new CachedData(getFlags(), bytes, bytes.length);
|
59
|
+
} catch (IOException ioe) {
|
60
|
+
throw ruby.newIOErrorFromException(ioe);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
public IRubyObject decode(CachedData d) {
|
65
|
+
try {
|
66
|
+
byte[] bytes;
|
67
|
+
if (d.getFlags() == 1) {
|
68
|
+
ByteArrayInputStream in = new ByteArrayInputStream(d.getData());
|
69
|
+
ZInputStream zin = new ZInputStream(in);
|
70
|
+
|
71
|
+
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
72
|
+
int nRead;
|
73
|
+
byte[] data = new byte[1024];
|
74
|
+
while ((nRead = zin.read(data, 0, data.length)) != -1) {
|
75
|
+
buffer.write(data, 0, nRead);
|
76
|
+
}
|
77
|
+
buffer.flush();
|
78
|
+
bytes = buffer.toByteArray();
|
79
|
+
zin.close();
|
80
|
+
} else {
|
81
|
+
bytes = d.getData();
|
82
|
+
}
|
83
|
+
|
84
|
+
return new UnmarshalStream(ruby, new ByteArrayInputStream(bytes), null, false, false).unmarshalObject();
|
85
|
+
} catch (IOException ioe) {
|
86
|
+
throw ruby.newIOErrorFromException(ioe);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
public int getMaxSize() {
|
91
|
+
return CachedData.MAX_SIZE;
|
92
|
+
}
|
93
|
+
|
94
|
+
public int getFlags() {
|
95
|
+
return flags;
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,325 @@
|
|
1
|
+
package com.openfeint.memcached;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
import java.net.InetSocketAddress;
|
5
|
+
import java.net.SocketAddress;
|
6
|
+
import java.util.ArrayList;
|
7
|
+
import java.util.Arrays;
|
8
|
+
import java.util.List;
|
9
|
+
import java.util.Map;
|
10
|
+
import java.util.concurrent.ExecutionException;
|
11
|
+
import net.spy.memcached.AddrUtil;
|
12
|
+
import net.spy.memcached.CachedData;
|
13
|
+
import net.spy.memcached.ConnectionFactoryBuilder;
|
14
|
+
import net.spy.memcached.ConnectionFactoryBuilder.Locator;
|
15
|
+
import net.spy.memcached.ConnectionFactoryBuilder.Protocol;
|
16
|
+
import net.spy.memcached.DefaultHashAlgorithm;
|
17
|
+
import net.spy.memcached.MemcachedClient;
|
18
|
+
import net.spy.memcached.transcoders.Transcoder;
|
19
|
+
import org.jruby.Ruby;
|
20
|
+
import org.jruby.RubyClass;
|
21
|
+
import org.jruby.RubyException;
|
22
|
+
import org.jruby.RubyHash;
|
23
|
+
import org.jruby.RubyObject;
|
24
|
+
import org.jruby.anno.JRubyClass;
|
25
|
+
import org.jruby.anno.JRubyMethod;
|
26
|
+
import org.jruby.exceptions.RaiseException;
|
27
|
+
import org.jruby.runtime.ThreadContext;
|
28
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
29
|
+
|
30
|
+
public class Memcached extends RubyObject {
|
31
|
+
private Ruby ruby;
|
32
|
+
|
33
|
+
private MemcachedClient client;
|
34
|
+
|
35
|
+
private Transcoder<IRubyObject> transcoder;
|
36
|
+
|
37
|
+
private int ttl;
|
38
|
+
|
39
|
+
public Memcached(final Ruby ruby, RubyClass rubyClass) {
|
40
|
+
super(ruby, rubyClass);
|
41
|
+
this.ruby = ruby;
|
42
|
+
}
|
43
|
+
|
44
|
+
@JRubyMethod
|
45
|
+
public IRubyObject initialize(ThreadContext context, IRubyObject servers) {
|
46
|
+
return initialize(context, servers, context.nil);
|
47
|
+
}
|
48
|
+
@JRubyMethod
|
49
|
+
public IRubyObject initialize(ThreadContext context, IRubyObject servers, IRubyObject options) {
|
50
|
+
List<InetSocketAddress> addresses;
|
51
|
+
if ("java.lang.String".equals(servers.getJavaClass().getName())) {
|
52
|
+
addresses = AddrUtil.getAddresses(servers.convertToString().toString());
|
53
|
+
} else {
|
54
|
+
addresses = AddrUtil.getAddresses((List<String>)servers.convertToArray());
|
55
|
+
}
|
56
|
+
try {
|
57
|
+
ConnectionFactoryBuilder builder = new ConnectionFactoryBuilder();
|
58
|
+
|
59
|
+
String distributionValue = null;
|
60
|
+
String hashValue = null;
|
61
|
+
String binaryValue = null;
|
62
|
+
String defaultTTL = null;
|
63
|
+
String transcoderValue = null;
|
64
|
+
if (!options.isNil()) {
|
65
|
+
RubyHash opts = options.convertToHash();
|
66
|
+
if (opts.containsKey(ruby.newSymbol("distribution"))) {
|
67
|
+
distributionValue = opts.get(ruby.newSymbol("distribution")).toString();
|
68
|
+
}
|
69
|
+
if (opts.containsKey(ruby.newSymbol("hash"))) {
|
70
|
+
hashValue = opts.get(ruby.newSymbol("hash")).toString();
|
71
|
+
}
|
72
|
+
if (opts.containsKey(ruby.newSymbol("binary_protocol"))) {
|
73
|
+
binaryValue = opts.get(ruby.newSymbol("binary_protocol")).toString();
|
74
|
+
}
|
75
|
+
if (opts.containsKey(ruby.newSymbol("default_ttl"))) {
|
76
|
+
defaultTTL = opts.get(ruby.newSymbol("default_ttl")).toString();
|
77
|
+
}
|
78
|
+
if (opts.containsKey(ruby.newSymbol("transcoder"))) {
|
79
|
+
transcoderValue = opts.get(ruby.newSymbol("transcoder")).toString();
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
if (distributionValue == null) {
|
84
|
+
distributionValue = "ketama";
|
85
|
+
}
|
86
|
+
if ("array_mod".equals(distributionValue)) {
|
87
|
+
builder.setLocatorType(Locator.ARRAY_MOD);
|
88
|
+
} else if ("ketama".equals(distributionValue) || "consistent_ketama".equals(distributionValue)) {
|
89
|
+
builder.setLocatorType(Locator.CONSISTENT);
|
90
|
+
} else {
|
91
|
+
throw newNotSupport(ruby, "distribution not support");
|
92
|
+
}
|
93
|
+
|
94
|
+
if (hashValue == null) {
|
95
|
+
hashValue = "fnv1_32";
|
96
|
+
}
|
97
|
+
if ("native".equals(hashValue)) {
|
98
|
+
builder.setHashAlg(DefaultHashAlgorithm.NATIVE_HASH);
|
99
|
+
} else if ("crc".equals(hashValue)) {
|
100
|
+
builder.setHashAlg(DefaultHashAlgorithm.CRC_HASH);
|
101
|
+
} else if ("fnv1_64".equals(hashValue)) {
|
102
|
+
builder.setHashAlg(DefaultHashAlgorithm.FNV1_64_HASH);
|
103
|
+
} else if ("fnv1a_64".equals(hashValue)) {
|
104
|
+
builder.setHashAlg(DefaultHashAlgorithm.FNV1A_64_HASH);
|
105
|
+
} else if ("fnv1_32".equals(hashValue)) {
|
106
|
+
builder.setHashAlg(DefaultHashAlgorithm.FNV1_32_HASH);
|
107
|
+
} else if ("fnv1a_32".equals(hashValue)) {
|
108
|
+
builder.setHashAlg(DefaultHashAlgorithm.FNV1A_32_HASH);
|
109
|
+
} else if ("ketama".equals(hashValue)) {
|
110
|
+
builder.setHashAlg(DefaultHashAlgorithm.KETAMA_HASH);
|
111
|
+
} else {
|
112
|
+
throw newNotSupport(ruby, "hash not support");
|
113
|
+
}
|
114
|
+
|
115
|
+
if ("true".equals(binaryValue)) {
|
116
|
+
builder.setProtocol(Protocol.BINARY);
|
117
|
+
}
|
118
|
+
|
119
|
+
if (defaultTTL == null) {
|
120
|
+
ttl = 604800;
|
121
|
+
} else {
|
122
|
+
ttl = Integer.parseInt(defaultTTL);
|
123
|
+
}
|
124
|
+
|
125
|
+
client = new MemcachedClient(builder.build(), addresses);
|
126
|
+
|
127
|
+
if ("marshal_zlib".equals(transcoderValue)) {
|
128
|
+
transcoder = new MarshalZlibTranscoder(ruby);
|
129
|
+
} else {
|
130
|
+
transcoder = new MarshalTranscoder(ruby);
|
131
|
+
}
|
132
|
+
} catch (IOException ioe) {
|
133
|
+
throw context.runtime.newIOErrorFromException(ioe);
|
134
|
+
}
|
135
|
+
|
136
|
+
return context.nil;
|
137
|
+
}
|
138
|
+
|
139
|
+
@JRubyMethod
|
140
|
+
public IRubyObject servers(ThreadContext context) {
|
141
|
+
List<IRubyObject> addresses = new ArrayList<IRubyObject>();
|
142
|
+
for (SocketAddress address : client.getAvailableServers()) {
|
143
|
+
String addressStr = address.toString();
|
144
|
+
if (addressStr.indexOf("/") == 0) {
|
145
|
+
addressStr = addressStr.replace("/", "");
|
146
|
+
}
|
147
|
+
addresses.add(ruby.newString(addressStr));
|
148
|
+
}
|
149
|
+
return ruby.newArray(addresses);
|
150
|
+
}
|
151
|
+
|
152
|
+
@JRubyMethod
|
153
|
+
public IRubyObject add(ThreadContext context, IRubyObject key, IRubyObject value) {
|
154
|
+
return add(context, key, value, ruby.newFixnum(ttl));
|
155
|
+
}
|
156
|
+
|
157
|
+
@JRubyMethod
|
158
|
+
public IRubyObject add(ThreadContext context, IRubyObject key, IRubyObject value, IRubyObject timeout) {
|
159
|
+
try {
|
160
|
+
boolean result = client.add(key.toString(), (int)timeout.convertToInteger().getLongValue(), value, transcoder).get();
|
161
|
+
if (result == false) {
|
162
|
+
throw newNotStored(ruby, "not stored");
|
163
|
+
}
|
164
|
+
return context.nil;
|
165
|
+
} catch (ExecutionException ee) {
|
166
|
+
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
|
167
|
+
} catch (InterruptedException ie) {
|
168
|
+
throw context.runtime.newThreadError(ie.getLocalizedMessage());
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
@JRubyMethod
|
173
|
+
public IRubyObject replace(ThreadContext context, IRubyObject key, IRubyObject value) {
|
174
|
+
return replace(context, key, value, ruby.newFixnum(ttl));
|
175
|
+
}
|
176
|
+
|
177
|
+
@JRubyMethod
|
178
|
+
public IRubyObject replace(ThreadContext context, IRubyObject key, IRubyObject value, IRubyObject timeout) {
|
179
|
+
try {
|
180
|
+
boolean result = client.replace(key.toString(), (int)timeout.convertToInteger().getLongValue(), value, transcoder).get();
|
181
|
+
if (result == false) {
|
182
|
+
throw newNotStored(ruby, "not stored");
|
183
|
+
}
|
184
|
+
return context.nil;
|
185
|
+
} catch (ExecutionException ee) {
|
186
|
+
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
|
187
|
+
} catch (InterruptedException ie) {
|
188
|
+
throw context.runtime.newThreadError(ie.getLocalizedMessage());
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
@JRubyMethod
|
193
|
+
public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value) {
|
194
|
+
return set(context, key, value, ruby.newFixnum(ttl));
|
195
|
+
}
|
196
|
+
|
197
|
+
@JRubyMethod
|
198
|
+
public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value, IRubyObject timeout) {
|
199
|
+
try {
|
200
|
+
boolean result = client.set(key.toString(), (int)timeout.convertToInteger().getLongValue(), value, transcoder).get();
|
201
|
+
if (result == false) {
|
202
|
+
throw newNotStored(ruby, "not stored");
|
203
|
+
}
|
204
|
+
return context.nil;
|
205
|
+
} catch (ExecutionException ee) {
|
206
|
+
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
|
207
|
+
} catch (InterruptedException ie) {
|
208
|
+
throw context.runtime.newThreadError(ie.getLocalizedMessage());
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
@JRubyMethod
|
213
|
+
public IRubyObject get(ThreadContext context, IRubyObject key) {
|
214
|
+
IRubyObject value = client.get(key.toString(), transcoder);
|
215
|
+
if (value == null) {
|
216
|
+
throw newNotFound(ruby, "not found");
|
217
|
+
}
|
218
|
+
return value;
|
219
|
+
}
|
220
|
+
|
221
|
+
@JRubyMethod
|
222
|
+
public IRubyObject incr(ThreadContext context, IRubyObject key) {
|
223
|
+
return incr(context, key, ruby.newFixnum(1), ruby.newFixnum(ttl));
|
224
|
+
}
|
225
|
+
|
226
|
+
@JRubyMethod
|
227
|
+
public IRubyObject incr(ThreadContext context, IRubyObject key, IRubyObject by) {
|
228
|
+
return incr(context, key, by, ruby.newFixnum(ttl));
|
229
|
+
}
|
230
|
+
|
231
|
+
@JRubyMethod
|
232
|
+
public IRubyObject incr(ThreadContext context, IRubyObject key, IRubyObject by, IRubyObject timeout) {
|
233
|
+
long result = client.incr(key.toString(), (int)by.convertToInteger().getLongValue(), 1, (int)timeout.convertToInteger().getLongValue());
|
234
|
+
return ruby.newFixnum(result);
|
235
|
+
}
|
236
|
+
|
237
|
+
@JRubyMethod
|
238
|
+
public IRubyObject decr(ThreadContext context, IRubyObject key) {
|
239
|
+
return decr(context, key, ruby.newFixnum(1), ruby.newFixnum(ttl));
|
240
|
+
}
|
241
|
+
|
242
|
+
@JRubyMethod
|
243
|
+
public IRubyObject decr(ThreadContext context, IRubyObject key, IRubyObject by) {
|
244
|
+
return decr(context, key, by, ruby.newFixnum(ttl));
|
245
|
+
}
|
246
|
+
|
247
|
+
@JRubyMethod
|
248
|
+
public IRubyObject decr(ThreadContext context, IRubyObject key, IRubyObject by, IRubyObject timeout) {
|
249
|
+
long result = client.decr(key.toString(), (int)by.convertToInteger().getLongValue(), 0, (int)timeout.convertToInteger().getLongValue());
|
250
|
+
return ruby.newFixnum(result);
|
251
|
+
}
|
252
|
+
|
253
|
+
@JRubyMethod
|
254
|
+
public IRubyObject delete(ThreadContext context, IRubyObject key) {
|
255
|
+
try {
|
256
|
+
boolean result = client.delete(key.toString()).get();
|
257
|
+
if (result == false) {
|
258
|
+
throw newNotFound(ruby, "not found");
|
259
|
+
}
|
260
|
+
return context.nil;
|
261
|
+
} catch (ExecutionException ee) {
|
262
|
+
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
|
263
|
+
} catch (InterruptedException ie) {
|
264
|
+
throw context.runtime.newThreadError(ie.getLocalizedMessage());
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
@JRubyMethod
|
269
|
+
public IRubyObject flush(ThreadContext context) {
|
270
|
+
try {
|
271
|
+
client.flush().get();
|
272
|
+
return context.nil;
|
273
|
+
} catch (ExecutionException ee) {
|
274
|
+
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
|
275
|
+
} catch (InterruptedException ie) {
|
276
|
+
throw context.runtime.newThreadError(ie.getLocalizedMessage());
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
@JRubyMethod
|
281
|
+
public IRubyObject stats(ThreadContext context) {
|
282
|
+
RubyHash results = RubyHash.newHash(ruby);
|
283
|
+
for(Map.Entry<SocketAddress, Map<String, String>> entry : client.getStats().entrySet()) {
|
284
|
+
RubyHash serverHash = RubyHash.newHash(ruby);
|
285
|
+
for(Map.Entry<String, String> server : entry.getValue().entrySet()) {
|
286
|
+
serverHash.op_aset(context, ruby.newString(server.getKey()), ruby.newString(server.getValue()));
|
287
|
+
}
|
288
|
+
results.op_aset(context, ruby.newString(entry.getKey().toString()), serverHash);
|
289
|
+
}
|
290
|
+
return results;
|
291
|
+
}
|
292
|
+
|
293
|
+
@JRubyMethod
|
294
|
+
public IRubyObject shutdown(ThreadContext context) {
|
295
|
+
client.shutdown();
|
296
|
+
|
297
|
+
return context.nil;
|
298
|
+
}
|
299
|
+
|
300
|
+
@JRubyClass(name="Memcached::Error", parent="RuntimeError")
|
301
|
+
public static class Error {}
|
302
|
+
@JRubyClass(name="Memcached::NotFound", parent="Memcached::Error")
|
303
|
+
public static class NotFound extends Error {}
|
304
|
+
@JRubyClass(name="Memcached::NotStored", parent="Memcached::Error")
|
305
|
+
public static class NotStored extends Error {}
|
306
|
+
@JRubyClass(name="Memcached::NotSupport", parent="Memcached::Error")
|
307
|
+
public static class NotSupport extends Error {}
|
308
|
+
|
309
|
+
static RaiseException newNotFound(Ruby ruby, String message) {
|
310
|
+
return newMemcachedError(ruby, "NotFound", message);
|
311
|
+
}
|
312
|
+
|
313
|
+
static RaiseException newNotStored(Ruby ruby, String message) {
|
314
|
+
return newMemcachedError(ruby, "NotStored", message);
|
315
|
+
}
|
316
|
+
|
317
|
+
static RaiseException newNotSupport(Ruby ruby, String message) {
|
318
|
+
return newMemcachedError(ruby, "NotSupport", message);
|
319
|
+
}
|
320
|
+
|
321
|
+
private static RaiseException newMemcachedError(Ruby ruby, String klass, String message) {
|
322
|
+
RubyClass errorClass = ruby.getModule("Memcached").getClass(klass);
|
323
|
+
return new RaiseException(RubyException.newException(ruby, errorClass, message), true);
|
324
|
+
}
|
325
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
package com.openfeint.memcached;
|
2
|
+
|
3
|
+
import java.io.ByteArrayInputStream;
|
4
|
+
import java.io.ByteArrayOutputStream;
|
5
|
+
import java.io.IOException;
|
6
|
+
import java.net.InetSocketAddress;
|
7
|
+
import java.net.SocketAddress;
|
8
|
+
import java.util.ArrayList;
|
9
|
+
import java.util.List;
|
10
|
+
import java.util.Map;
|
11
|
+
import java.util.concurrent.ExecutionException;
|
12
|
+
import net.spy.memcached.CachedData;
|
13
|
+
import net.spy.memcached.MemcachedClient;
|
14
|
+
import net.spy.memcached.transcoders.Transcoder;
|
15
|
+
import org.jruby.Ruby;
|
16
|
+
import org.jruby.RubyClass;
|
17
|
+
import org.jruby.RubyException;
|
18
|
+
import org.jruby.RubyHash;
|
19
|
+
import org.jruby.RubyObject;
|
20
|
+
import org.jruby.RubyString;
|
21
|
+
import org.jruby.RubySymbol;
|
22
|
+
import org.jruby.anno.JRubyClass;
|
23
|
+
import org.jruby.anno.JRubyMethod;
|
24
|
+
import org.jruby.exceptions.RaiseException;
|
25
|
+
import org.jruby.runtime.ObjectAllocator;
|
26
|
+
import org.jruby.runtime.ThreadContext;
|
27
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
28
|
+
import org.jruby.runtime.load.Library;
|
29
|
+
import org.jruby.runtime.marshal.MarshalStream;
|
30
|
+
import org.jruby.runtime.marshal.UnmarshalStream;
|
31
|
+
|
32
|
+
public class MemcachedLibrary implements Library {
|
33
|
+
private Ruby ruby;
|
34
|
+
|
35
|
+
public void load(final Ruby ruby, boolean bln) throws IOException {
|
36
|
+
this.ruby = ruby;
|
37
|
+
|
38
|
+
RubyClass memcached = ruby.defineClass("Memcached", ruby.getObject(), new ObjectAllocator() {
|
39
|
+
public IRubyObject allocate(Ruby ruby, RubyClass rc) {
|
40
|
+
return new Memcached(ruby, rc);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
memcached.defineAnnotatedMethods(Memcached.class);
|
45
|
+
|
46
|
+
RubyClass runtimeError = ruby.getRuntimeError();
|
47
|
+
RubyClass memcachedError = memcached.defineClassUnder("Error", runtimeError, runtimeError.getAllocator());
|
48
|
+
memcached.defineClassUnder("NotFound", memcachedError, memcachedError.getAllocator());
|
49
|
+
memcached.defineClassUnder("NotStored", memcachedError, memcachedError.getAllocator());
|
50
|
+
memcached.defineClassUnder("NotSupport", memcachedError, memcachedError.getAllocator());
|
51
|
+
}
|
52
|
+
}
|
Binary file
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: jruby-memcached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Richard Huang
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-07
|
13
|
+
date: 2012-08-07 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -58,9 +58,11 @@ files:
|
|
58
58
|
- pom.xml
|
59
59
|
- spec/memcached_spec.rb
|
60
60
|
- spec/spec_helper.rb
|
61
|
+
- src/main/java/com/openfeint/memcached/MarshalTranscoder.java
|
62
|
+
- src/main/java/com/openfeint/memcached/MarshalZlibTranscoder.java
|
63
|
+
- src/main/java/com/openfeint/memcached/Memcached.java
|
64
|
+
- src/main/java/com/openfeint/memcached/MemcachedLibrary.java
|
61
65
|
- src/main/java/net/spy/memcached/KetamaNodeLocator.java
|
62
|
-
- src/main/java/net/spy/memcached/ReturnData.java
|
63
|
-
- src/main/java/net/spy/memcached/transcoders/SimpleTranscoder.java
|
64
66
|
- src/main/java/net/spy/memcached/util/DefaultKetamaNodeLocatorConfiguration.java
|
65
67
|
- target/spymemcached-ext-0.0.1.jar
|
66
68
|
homepage: https://github.com/aurorafeint/jruby-memcached
|
@@ -86,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
88
|
requirements: []
|
87
89
|
|
88
90
|
rubyforge_project:
|
89
|
-
rubygems_version: 1.8.
|
91
|
+
rubygems_version: 1.8.24
|
90
92
|
signing_key:
|
91
93
|
specification_version: 3
|
92
94
|
summary: jruby compatible memcached client
|
@@ -1,20 +0,0 @@
|
|
1
|
-
package net.spy.memcached;
|
2
|
-
|
3
|
-
public class ReturnData {
|
4
|
-
private int flags;
|
5
|
-
private byte[] data;
|
6
|
-
|
7
|
-
public ReturnData(int flags, byte[] data) {
|
8
|
-
this.flags = flags;
|
9
|
-
this.data = data;
|
10
|
-
}
|
11
|
-
|
12
|
-
|
13
|
-
public int getFlags() {
|
14
|
-
return flags;
|
15
|
-
}
|
16
|
-
|
17
|
-
public byte[] getData() {
|
18
|
-
return data;
|
19
|
-
}
|
20
|
-
}
|
@@ -1,53 +0,0 @@
|
|
1
|
-
package net.spy.memcached.transcoders;
|
2
|
-
|
3
|
-
import net.spy.memcached.CachedData;
|
4
|
-
import net.spy.memcached.ReturnData;
|
5
|
-
import net.spy.memcached.transcoders.Transcoder;
|
6
|
-
|
7
|
-
/**
|
8
|
-
*
|
9
|
-
* SimpleTranscoder didn't do any serializing/deserializing or compression/decompression.
|
10
|
-
* Ruby will convert object to string by Marshal and finally passing bytes[].
|
11
|
-
*
|
12
|
-
*/
|
13
|
-
public class SimpleTranscoder implements Transcoder<Object> {
|
14
|
-
private final int maxSize;
|
15
|
-
private int flags;
|
16
|
-
|
17
|
-
public SimpleTranscoder() {
|
18
|
-
this(CachedData.MAX_SIZE, 0);
|
19
|
-
}
|
20
|
-
|
21
|
-
public SimpleTranscoder(int flags) {
|
22
|
-
this(CachedData.MAX_SIZE, flags);
|
23
|
-
}
|
24
|
-
|
25
|
-
public SimpleTranscoder(int maxSize, int flags) {
|
26
|
-
this.maxSize = maxSize;
|
27
|
-
this.flags = flags;
|
28
|
-
}
|
29
|
-
|
30
|
-
public boolean asyncDecode(CachedData d) {
|
31
|
-
return false;
|
32
|
-
}
|
33
|
-
|
34
|
-
public CachedData encode(Object o) {
|
35
|
-
return new CachedData(getFlags(), (byte[]) o, getMaxSize());
|
36
|
-
}
|
37
|
-
|
38
|
-
public Object decode(CachedData d) {
|
39
|
-
return new ReturnData(d.getFlags(), d.getData());
|
40
|
-
}
|
41
|
-
|
42
|
-
public int getMaxSize() {
|
43
|
-
return maxSize;
|
44
|
-
}
|
45
|
-
|
46
|
-
public int getFlags() {
|
47
|
-
return flags;
|
48
|
-
}
|
49
|
-
|
50
|
-
public void setFlags(int flags) {
|
51
|
-
this.flags = flags;
|
52
|
-
}
|
53
|
-
}
|