jubatus 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +4 -1
  2. data/README.rst +1 -1
  3. data/Rakefile +8 -0
  4. data/VERSION +1 -1
  5. data/{test → integration_test}/jubatus_test/anomaly/test.rb +22 -23
  6. data/{test → integration_test}/jubatus_test/classifier/test.rb +10 -15
  7. data/integration_test/jubatus_test/clustering/test.rb +133 -0
  8. data/integration_test/jubatus_test/error/test.rb +51 -0
  9. data/{test → integration_test}/jubatus_test/graph/test.rb +15 -30
  10. data/integration_test/jubatus_test/nearest_neighbor/test.rb +86 -0
  11. data/integration_test/jubatus_test/recommender/test.rb +111 -0
  12. data/{test → integration_test}/jubatus_test/regression/test.rb +10 -15
  13. data/integration_test/jubatus_test/stat/test.rb +108 -0
  14. data/{test → integration_test}/jubatus_test/test_util.rb +1 -0
  15. data/jubatus.gemspec +1 -1
  16. data/lib/jubatus/anomaly/client.rb +34 -33
  17. data/lib/jubatus/anomaly/types.rb +30 -18
  18. data/lib/jubatus/classifier/client.rb +22 -28
  19. data/lib/jubatus/classifier/types.rb +56 -33
  20. data/lib/jubatus/clustering/client.rb +51 -0
  21. data/lib/jubatus/clustering/types.rb +44 -0
  22. data/lib/jubatus/common/client.rb +83 -0
  23. data/lib/jubatus/common/datum.rb +85 -0
  24. data/lib/jubatus/common/message_string_generator.rb +41 -0
  25. data/lib/jubatus/common/types.rb +247 -0
  26. data/lib/jubatus/common.rb +4 -0
  27. data/lib/jubatus/graph/client.rb +83 -60
  28. data/lib/jubatus/graph/types.rb +146 -85
  29. data/lib/jubatus/nearest_neighbor/client.rb +53 -0
  30. data/lib/jubatus/nearest_neighbor/types.rb +44 -0
  31. data/lib/jubatus/recommender/client.rb +50 -44
  32. data/lib/jubatus/recommender/types.rb +29 -26
  33. data/lib/jubatus/regression/client.rb +22 -28
  34. data/lib/jubatus/regression/types.rb +30 -18
  35. data/lib/jubatus/stat/client.rb +37 -38
  36. data/lib/jubatus/stat/types.rb +5 -4
  37. data/test/jubatus_test/common/client_test.rb +104 -0
  38. data/test/jubatus_test/common/datum_test.rb +43 -0
  39. data/test/jubatus_test/common/message_string_generator_test.rb +50 -0
  40. data/test/jubatus_test/common/types_test.rb +73 -0
  41. metadata +29 -16
  42. data/test/jubatus_test/recommender/test.rb +0 -122
  43. data/test/jubatus_test/stat/test.rb +0 -109
@@ -0,0 +1,83 @@
1
+ module Jubatus
2
+ module Common
3
+
4
+ class InterfaceMismatch < Exception; end
5
+ class UnknownMethod < InterfaceMismatch; end
6
+ class TypeMismatch < InterfaceMismatch; end
7
+
8
+ class Client
9
+ def initialize(client, name)
10
+ @client = client
11
+ @name = name
12
+ end
13
+
14
+ def call(method, args, ret_type, args_type)
15
+ if args.size != args_type.size
16
+ raise "number of arguemnts for \"%s\" must to be %d, but %d arguments are given" % [method, args_type.size, args.size]
17
+ end
18
+ values = [@name]
19
+ args.zip(args_type).each do |v, t|
20
+ values << t.to_msgpack(v)
21
+ end
22
+ future = @client.call_async_apply(method, values)
23
+ future.attach_error_handler do |error, result|
24
+ error_handler(error, result)
25
+ end
26
+ ret = future.get
27
+
28
+ if ret_type != nil
29
+ return ret_type.from_msgpack(ret)
30
+ end
31
+ end
32
+
33
+ def error_handler(error, result)
34
+ if error == 1
35
+ raise UnknownMethod
36
+ elsif error == 2
37
+ raise TypeMismatch
38
+ else
39
+ raise MessagePack::RPC::RPCError.create(error, result)
40
+ end
41
+ end
42
+ end
43
+
44
+ class ClientBase
45
+ def initialize(host, port, name, timeout_sec)
46
+ @cli = MessagePack::RPC::Client.new(host, port)
47
+ @cli.timeout = timeout_sec
48
+ @jubatus_client = Jubatus::Common::Client.new(@cli, name)
49
+ end
50
+
51
+ def self.connect(host, port, name, timeout_sec, &block)
52
+ begin
53
+ client = self.new(host, port, name, timeout_sec)
54
+ block.call(client)
55
+ ensure
56
+ client.get_client.close
57
+ end
58
+ end
59
+
60
+ def get_client
61
+ @cli
62
+ end
63
+
64
+ def get_config
65
+ @jubatus_client.call("get_config", [], TString.new, [])
66
+ end
67
+
68
+ def save(id)
69
+ @jubatus_client.call("save", [id], TBool.new, [TString.new])
70
+ end
71
+
72
+ def load(id)
73
+ @jubatus_client.call("load", [id], TBool.new, [TString.new])
74
+ end
75
+
76
+ def get_status
77
+ @jubatus_client.call("get_status", [], TMap.new(TString.new, TMap.new(
78
+ TString.new, TString.new)), [])
79
+ end
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,85 @@
1
+ require 'jubatus/common'
2
+ module Jubatus
3
+ module Common
4
+
5
+ class Datum
6
+ include Jubatus::Common
7
+ TYPE = TTuple.new(TList.new(TTuple.new(TString.new, TString.new)),
8
+ TList.new(TTuple.new(TString.new, TFloat.new)),
9
+ TList.new(TTuple.new(TString.new, TString.new)))
10
+
11
+ def initialize(values = {})
12
+ @string_values = []
13
+ @num_values = []
14
+ @binary_values = []
15
+ values.each { |k, v|
16
+ raise TypeError unless String === k
17
+ if String === v
18
+ @string_values << [k, v]
19
+ elsif Integer === v
20
+ @num_values << [k, v.to_f]
21
+ elsif Float === v
22
+ @num_values << [k, v]
23
+ else
24
+ raise TypeError
25
+ end
26
+ }
27
+ end
28
+
29
+ def add_string(key, value)
30
+ raise TypeError unless String === key
31
+ if String === value
32
+ @string_values << [k, v]
33
+ else
34
+ raise TypeError
35
+ end
36
+ end
37
+
38
+ def add_number(key, value)
39
+ raise TypeError unless String === key
40
+ if Integer === v
41
+ @num_values << [k, v.to_f]
42
+ elsif Float === v
43
+ @num_values << [k, v]
44
+ else
45
+ raise TypeError
46
+ end
47
+ end
48
+
49
+ def add_binary(key, value)
50
+ raise TypeError unless String === key
51
+ if String === value
52
+ @binary_values << [k, v]
53
+ else
54
+ raise TypeError
55
+ end
56
+ end
57
+
58
+ def to_msgpack(out = '')
59
+ t = [@string_values, @num_values, @binary_values]
60
+ return TYPE.to_msgpack(t)
61
+ end
62
+
63
+ def Datum.from_msgpack(m)
64
+ val = TYPE.from_msgpack(m)
65
+ d = Datum.new
66
+ d.string_values.concat(m[0])
67
+ d.num_values.concat(m[1])
68
+ d.binary_values.concat(m[2])
69
+ return d
70
+ end
71
+
72
+ def to_s
73
+ gen = Jubatus::Common::MessageStringGenerator.new
74
+ gen.open("datum")
75
+ gen.add("string_values", @string_values)
76
+ gen.add("num_values", @num_values)
77
+ gen.add("binary_values", @binary_values)
78
+ gen.close()
79
+ return gen.to_s
80
+ end
81
+ attr_reader :string_values, :num_values, :binary_values
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,41 @@
1
+ module Jubatus
2
+ module Common
3
+
4
+ class MessageStringGenerator
5
+ OPEN = "{"
6
+ COLON = ": "
7
+ DELIMITER = ", "
8
+ CLOSE = "}"
9
+
10
+ def initialize()
11
+ @buf = []
12
+ @first = true
13
+ end
14
+
15
+ def open(typ)
16
+ @buf << typ.to_s
17
+ @buf << OPEN
18
+ end
19
+
20
+ def add(key, value)
21
+ if @first
22
+ @first = false
23
+ else
24
+ @buf << DELIMITER
25
+ end
26
+ @buf << key.to_s
27
+ @buf << COLON
28
+ @buf << value.to_s
29
+ end
30
+
31
+ def close
32
+ @buf << CLOSE
33
+ end
34
+
35
+ def to_s
36
+ @buf.join
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,247 @@
1
+ module Jubatus
2
+ module Common
3
+
4
+ class TypeError < Exception; end
5
+ class ValueError < Exception; end
6
+
7
+ def self.check_type(value, typ)
8
+ if not (typ === value)
9
+ raise TypeError, "type %s is expected, but %s is given" % [typ, value.class]
10
+ end
11
+ end
12
+
13
+ def self.check_types(value, types)
14
+ types.each do |t|
15
+ return if t === value
16
+ end
17
+ t = types.map { |t| t.to_s }.join(", ")
18
+ raise TypeError, "type %s is expected, but %s is given" % [t, value.class]
19
+ end
20
+
21
+ class TPrimitive
22
+ def initialize(types)
23
+ @types = types
24
+ end
25
+
26
+ def from_msgpack(m)
27
+ Jubatus::Common.check_types(m, @types)
28
+ return m
29
+ end
30
+
31
+ def to_msgpack(m)
32
+ Jubatus::Common.check_types(m, @types)
33
+ return m
34
+ end
35
+ end
36
+
37
+ class TInt < TPrimitive
38
+ def initialize(signed, byts)
39
+ if signed
40
+ @max = (1 << (8 * byts - 1)) - 1
41
+ @min = - (1 << (8 * byts - 1))
42
+ else
43
+ @max = (1 << (8 * byts)) - 1
44
+ @min = 0
45
+ end
46
+ end
47
+
48
+ def from_msgpack(m)
49
+ Jubatus::Common.check_type(m, Integer)
50
+ if not (@min <= m and m <= @max)
51
+ raise ValueError, "int value must be in (%d, %d), but %d is given" % [@min, @max, m]
52
+ end
53
+ return m
54
+ end
55
+
56
+ def to_msgpack(m)
57
+ Jubatus::Common.check_type(m, Integer)
58
+ if not (@min <= m and m <= @max)
59
+ raise ValueError, "int value must be in (%d, %d), but %d is given" % [@min, @max, m]
60
+ end
61
+ return m
62
+ end
63
+ end
64
+
65
+ class TFloat < TPrimitive
66
+ def initialize
67
+ super([Float])
68
+ end
69
+ end
70
+
71
+ class TBool < TPrimitive
72
+ def initialize
73
+ super([TrueClass, FalseClass])
74
+ end
75
+ end
76
+
77
+ class TString < TPrimitive
78
+ def initialize()
79
+ super([String])
80
+ end
81
+ end
82
+
83
+ class TDatum
84
+ def from_msgpack(m)
85
+ Jubatus::Common::Datum.from_msgpack(m)
86
+ end
87
+
88
+ def to_msgpack(m)
89
+ Jubatus::Common.check_type(m, Jubatus::Common::Datum)
90
+ m.to_msgpack()
91
+ end
92
+ end
93
+
94
+ class TRaw < TPrimitive
95
+ def initialize()
96
+ super([String])
97
+ end
98
+ end
99
+
100
+ class TNullable
101
+ def initialize(type)
102
+ @type = type
103
+ end
104
+
105
+ def from_msgpack(m)
106
+ if m.nil?
107
+ return nil
108
+ else
109
+ @type.from_msgpack(m)
110
+ end
111
+ end
112
+
113
+ def to_msgpack(m)
114
+ if m.nil?
115
+ nil
116
+ else
117
+ @type.to_msgpack(m)
118
+ end
119
+ end
120
+ end
121
+
122
+ class TList
123
+ def initialize(type)
124
+ @type = type
125
+ end
126
+
127
+ def from_msgpack(m)
128
+ Jubatus::Common.check_type(m, Array)
129
+ return m.map { |v| @type.from_msgpack(v) }
130
+ end
131
+
132
+ def to_msgpack(m)
133
+ Jubatus::Common.check_type(m, Array)
134
+ return m.map { |v| @type.to_msgpack(v) }
135
+ end
136
+ end
137
+
138
+ class TMap
139
+ def initialize(key, value)
140
+ @key = key
141
+ @value = value
142
+ end
143
+
144
+ def from_msgpack(m)
145
+ Jubatus::Common.check_type(m, Hash)
146
+ dic = {}
147
+ m.each do |k, v|
148
+ dic[@key.from_msgpack(k)] = @value.from_msgpack(v)
149
+ end
150
+ return dic
151
+ end
152
+
153
+ def to_msgpack(m)
154
+ Jubatus::Common.check_type(m, Hash)
155
+ dic = {}
156
+ m.each do |k, v|
157
+ dic[@key.to_msgpack(k)] = @value.to_msgpack(v)
158
+ end
159
+ return dic
160
+ end
161
+ end
162
+
163
+ class TTuple
164
+ def initialize(*types)
165
+ @types = types
166
+ end
167
+
168
+ def check_tuple(m)
169
+ Jubatus::Common.check_type(m, Array)
170
+ if m.size != @types.size
171
+ raise TypeError, "size of tuple is %d, but %d is expected: %s" % [m.size, @types.size, m.to_s]
172
+ end
173
+ end
174
+
175
+ def from_msgpack(m)
176
+ check_tuple(m)
177
+ tpl = []
178
+ @types.zip(m).each do |type, x|
179
+ tpl << type.from_msgpack(x)
180
+ end
181
+ return tpl
182
+ end
183
+
184
+ def to_msgpack(m)
185
+ check_tuple(m)
186
+ tpl = []
187
+ @types.zip(m).each do |type, x|
188
+ tpl << type.to_msgpack(x)
189
+ end
190
+ return tpl
191
+ end
192
+ end
193
+
194
+ class TUserDef
195
+ def initialize(type)
196
+ @type = type
197
+ end
198
+
199
+ def from_msgpack(m)
200
+ return @type.from_msgpack(m)
201
+ end
202
+
203
+ def to_msgpack(m)
204
+ if @type === m
205
+ return m.to_msgpack()
206
+ elsif Array === m
207
+ return @type::TYPE.to_msgpack(m)
208
+ else
209
+ raise TypeError, "type %s or Array are expected, but %s is given" % [@type, m.class]
210
+ end
211
+ end
212
+ end
213
+
214
+ class TObject
215
+ def from_msgpack(m)
216
+ return m
217
+ end
218
+
219
+ def to_msgpack(m)
220
+ return m
221
+ end
222
+ end
223
+
224
+ class TEnum
225
+ def initialize(values)
226
+ @values = values
227
+ end
228
+
229
+ def from_msgpack(m)
230
+ Jubatus::Common.check_type(m, Integer)
231
+ if not (@values.include?(m))
232
+ raise ValueError
233
+ end
234
+ return m
235
+ end
236
+
237
+ def to_msgpack(m)
238
+ Jubatus::Common.check_type(m, Integer)
239
+ if not (@values.inlcude?(m))
240
+ raise ValueError
241
+ end
242
+ return m
243
+ end
244
+ end
245
+
246
+ end
247
+ end
@@ -0,0 +1,4 @@
1
+ require 'jubatus/common/message_string_generator'
2
+ require 'jubatus/common/types'
3
+ require 'jubatus/common/datum'
4
+ require 'jubatus/common/client'
@@ -1,92 +1,115 @@
1
- # This file is auto-generated from graph.idl
1
+ # This file is auto-generated from graph.idl(0.4.5-347-g86989a6) with jenerator version 0.4.5-418-gd2d5f04/develop
2
2
  # *** DO NOT EDIT ***
3
3
 
4
4
  require 'rubygems'
5
5
  require 'msgpack/rpc'
6
+ require 'jubatus/common'
6
7
  require File.join(File.dirname(__FILE__), 'types')
7
8
 
8
9
  module Jubatus
10
+
9
11
  module Graph
10
12
  module Client
11
13
 
12
- class Graph
13
- def initialize(host, port)
14
- @cli = MessagePack::RPC::Client.new(host, port)
15
- end
16
- def get_client
17
- @cli
18
- end
19
- def get_config(name)
20
- @cli.call(:get_config, name)
21
- end
22
- def create_node(name)
23
- @cli.call(:create_node, name)
14
+ class Graph < Jubatus::Common::ClientBase
15
+ include Jubatus::Common
16
+ def initialize(host, port, name, timeout_sec=10)
17
+ super
24
18
  end
25
- def remove_node(name, node_id)
26
- @cli.call(:remove_node, name, node_id)
27
- end
28
- def update_node(name, node_id, property)
29
- @cli.call(:update_node, name, node_id, property)
30
- end
31
- def create_edge(name, node_id, e)
32
- @cli.call(:create_edge, name, node_id, e)
19
+
20
+ def create_node
21
+ @jubatus_client.call("create_node", [], TString.new, [])
33
22
  end
34
- def update_edge(name, node_id, edge_id, e)
35
- @cli.call(:update_edge, name, node_id, edge_id, e)
23
+
24
+ def remove_node(node_id)
25
+ @jubatus_client.call("remove_node", [node_id], TBool.new, [TString.new])
36
26
  end
37
- def remove_edge(name, node_id, edge_id)
38
- @cli.call(:remove_edge, name, node_id, edge_id)
27
+
28
+ def update_node(node_id, property)
29
+ @jubatus_client.call("update_node", [node_id, property], TBool.new,
30
+ [TString.new, TMap.new(TString.new, TString.new)])
39
31
  end
40
- def get_centrality(name, node_id, centrality_type, query)
41
- @cli.call(:get_centrality, name, node_id, centrality_type, query)
32
+
33
+ def create_edge(node_id, e)
34
+ @jubatus_client.call("create_edge", [node_id, e], TInt.new(false, 8),
35
+ [TString.new, TUserDef.new(Edge)])
42
36
  end
43
- def add_centrality_query(name, query)
44
- @cli.call(:add_centrality_query, name, query)
37
+
38
+ def update_edge(node_id, edge_id, e)
39
+ @jubatus_client.call("update_edge", [node_id, edge_id, e], TBool.new,
40
+ [TString.new, TInt.new(false, 8), TUserDef.new(Edge)])
45
41
  end
46
- def add_shortest_path_query(name, query)
47
- @cli.call(:add_shortest_path_query, name, query)
42
+
43
+ def remove_edge(node_id, edge_id)
44
+ @jubatus_client.call("remove_edge", [node_id, edge_id], TBool.new,
45
+ [TString.new, TInt.new(false, 8)])
48
46
  end
49
- def remove_centrality_query(name, query)
50
- @cli.call(:remove_centrality_query, name, query)
47
+
48
+ def get_centrality(node_id, centrality_type, query)
49
+ @jubatus_client.call("get_centrality", [node_id, centrality_type, query],
50
+ TFloat.new, [TString.new, TInt.new(true, 4), TUserDef.new(PresetQuery)])
51
51
  end
52
- def remove_shortest_path_query(name, query)
53
- @cli.call(:remove_shortest_path_query, name, query)
52
+
53
+ def add_centrality_query(query)
54
+ @jubatus_client.call("add_centrality_query", [query], TBool.new,
55
+ [TUserDef.new(PresetQuery)])
54
56
  end
55
- def get_shortest_path(name, query)
56
- @cli.call(:get_shortest_path, name, query)
57
+
58
+ def add_shortest_path_query(query)
59
+ @jubatus_client.call("add_shortest_path_query", [query], TBool.new,
60
+ [TUserDef.new(PresetQuery)])
57
61
  end
58
- def update_index(name)
59
- @cli.call(:update_index, name)
62
+
63
+ def remove_centrality_query(query)
64
+ @jubatus_client.call("remove_centrality_query", [query], TBool.new,
65
+ [TUserDef.new(PresetQuery)])
60
66
  end
61
- def clear(name)
62
- @cli.call(:clear, name)
67
+
68
+ def remove_shortest_path_query(query)
69
+ @jubatus_client.call("remove_shortest_path_query", [query], TBool.new,
70
+ [TUserDef.new(PresetQuery)])
63
71
  end
64
- def get_node(name, node_id)
65
- Node.from_tuple(@cli.call(:get_node, name, node_id))
72
+
73
+ def get_shortest_path(query)
74
+ @jubatus_client.call("get_shortest_path", [query], TList.new(TString.new),
75
+ [TUserDef.new(ShortestPathQuery)])
66
76
  end
67
- def get_edge(name, node_id, edge_id)
68
- Edge.from_tuple(@cli.call(:get_edge, name, node_id, edge_id))
77
+
78
+ def update_index
79
+ @jubatus_client.call("update_index", [], TBool.new, [])
69
80
  end
70
- def save(name, id)
71
- @cli.call(:save, name, id)
81
+
82
+ def clear
83
+ @jubatus_client.call("clear", [], TBool.new, [])
72
84
  end
73
- def load(name, id)
74
- @cli.call(:load, name, id)
85
+
86
+ def get_node(node_id)
87
+ @jubatus_client.call("get_node", [node_id], TUserDef.new(Node),
88
+ [TString.new])
75
89
  end
76
- def get_status(name)
77
- @cli.call(:get_status, name)
90
+
91
+ def get_edge(node_id, edge_id)
92
+ @jubatus_client.call("get_edge", [node_id, edge_id], TUserDef.new(Edge),
93
+ [TString.new, TInt.new(false, 8)])
78
94
  end
79
- def create_node_here(name, node_id)
80
- @cli.call(:create_node_here, name, node_id)
95
+
96
+ def create_node_here(node_id)
97
+ @jubatus_client.call("create_node_here", [node_id], TBool.new,
98
+ [TString.new])
81
99
  end
82
- def remove_global_node(name, node_id)
83
- @cli.call(:remove_global_node, name, node_id)
100
+
101
+ def remove_global_node(node_id)
102
+ @jubatus_client.call("remove_global_node", [node_id], TBool.new,
103
+ [TString.new])
84
104
  end
85
- def create_edge_here(name, edge_id, e)
86
- @cli.call(:create_edge_here, name, edge_id, e)
105
+
106
+ def create_edge_here(edge_id, e)
107
+ @jubatus_client.call("create_edge_here", [edge_id, e], TBool.new, [TInt.new(
108
+ false, 8), TUserDef.new(Edge)])
87
109
  end
88
110
  end
89
111
 
90
- end
91
- end
92
- end
112
+ end # Client
113
+ end # Graph
114
+
115
+ end # Jubatus