jubatus 0.4.1 → 0.5.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.
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