tempest_db 0.13.2 → 0.14.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.
@@ -6,88 +6,204 @@
6
6
 
7
7
  require 'thrift'
8
8
 
9
- class InvalidNodeIdException < ::Thrift::Exception
10
- include ::Thrift::Struct, ::Thrift::Struct_Union
11
- def initialize(message=nil)
12
- super()
13
- self.message = message
14
- end
9
+ module Teapot
10
+ module TempestDB
11
+ module DegreeFilterTypes
12
+ INDEGREE_MIN = 0
13
+ INDEGREE_MAX = 1
14
+ OUTDEGREE_MIN = 2
15
+ OUTDEGREE_MAX = 3
16
+ VALUE_MAP = {0 => "INDEGREE_MIN", 1 => "INDEGREE_MAX", 2 => "OUTDEGREE_MIN", 3 => "OUTDEGREE_MAX"}
17
+ VALID_VALUES = Set.new([INDEGREE_MIN, INDEGREE_MAX, OUTDEGREE_MIN, OUTDEGREE_MAX]).freeze
18
+ end
19
+
20
+ class Node
21
+ include ::Thrift::Struct, ::Thrift::Struct_Union
22
+ TYPE = 1
23
+ ID = 2
24
+
25
+ FIELDS = {
26
+ TYPE => {:type => ::Thrift::Types::STRING, :name => 'type'},
27
+ ID => {:type => ::Thrift::Types::STRING, :name => 'id'}
28
+ }
29
+
30
+ def struct_fields; FIELDS; end
31
+
32
+ def validate
33
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field type is unset!') unless @type
34
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field id is unset!') unless @id
35
+ end
36
+
37
+ ::Thrift::Struct.generate_accessors self
38
+ end
39
+
40
+ class MonteCarloPageRankParams
41
+ include ::Thrift::Struct, ::Thrift::Struct_Union
42
+ NUMSTEPS = 1
43
+ RESETPROBABILITY = 2
44
+ MAXINTERMEDIATENODEDEGREE = 3
45
+ MINREPORTEDVISITS = 4
46
+ MAXRESULTCOUNT = 5
47
+
48
+ FIELDS = {
49
+ NUMSTEPS => {:type => ::Thrift::Types::I32, :name => 'numSteps'},
50
+ RESETPROBABILITY => {:type => ::Thrift::Types::DOUBLE, :name => 'resetProbability'},
51
+ MAXINTERMEDIATENODEDEGREE => {:type => ::Thrift::Types::I32, :name => 'maxIntermediateNodeDegree', :default => 1000, :optional => true},
52
+ MINREPORTEDVISITS => {:type => ::Thrift::Types::I32, :name => 'minReportedVisits', :optional => true},
53
+ MAXRESULTCOUNT => {:type => ::Thrift::Types::I32, :name => 'maxResultCount', :optional => true}
54
+ }
55
+
56
+ def struct_fields; FIELDS; end
57
+
58
+ def validate
59
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field numSteps is unset!') unless @numSteps
60
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field resetProbability is unset!') unless @resetProbability
61
+ end
62
+
63
+ ::Thrift::Struct.generate_accessors self
64
+ end
65
+
66
+ class BidirectionalPPRParams
67
+ include ::Thrift::Struct, ::Thrift::Struct_Union
68
+ RELATIVEERROR = 1
69
+ RESETPROBABILITY = 2
70
+ MINPROBABILITY = 3
15
71
 
16
- MESSAGE = 1
72
+ FIELDS = {
73
+ RELATIVEERROR => {:type => ::Thrift::Types::DOUBLE, :name => 'relativeError'},
74
+ RESETPROBABILITY => {:type => ::Thrift::Types::DOUBLE, :name => 'resetProbability'},
75
+ MINPROBABILITY => {:type => ::Thrift::Types::DOUBLE, :name => 'minProbability', :optional => true}
76
+ }
77
+
78
+ def struct_fields; FIELDS; end
79
+
80
+ def validate
81
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field relativeError is unset!') unless @relativeError
82
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field resetProbability is unset!') unless @resetProbability
83
+ end
84
+
85
+ ::Thrift::Struct.generate_accessors self
86
+ end
17
87
 
18
- FIELDS = {
19
- MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
20
- }
88
+ class InvalidNodeIdException < ::Thrift::Exception
89
+ include ::Thrift::Struct, ::Thrift::Struct_Union
90
+ def initialize(message=nil)
91
+ super()
92
+ self.message = message
93
+ end
21
94
 
22
- def struct_fields; FIELDS; end
95
+ MESSAGE = 1
23
96
 
24
- def validate
25
- end
97
+ FIELDS = {
98
+ MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
99
+ }
26
100
 
27
- ::Thrift::Struct.generate_accessors self
28
- end
101
+ def struct_fields; FIELDS; end
29
102
 
30
- class InvalidIndexException < ::Thrift::Exception
31
- include ::Thrift::Struct, ::Thrift::Struct_Union
32
- def initialize(message=nil)
33
- super()
34
- self.message = message
35
- end
103
+ def validate
104
+ end
36
105
 
37
- MESSAGE = 1
106
+ ::Thrift::Struct.generate_accessors self
107
+ end
38
108
 
39
- FIELDS = {
40
- MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
41
- }
109
+ class InvalidIndexException < ::Thrift::Exception
110
+ include ::Thrift::Struct, ::Thrift::Struct_Union
111
+ def initialize(message=nil)
112
+ super()
113
+ self.message = message
114
+ end
42
115
 
43
- def struct_fields; FIELDS; end
116
+ MESSAGE = 1
44
117
 
45
- def validate
46
- end
118
+ FIELDS = {
119
+ MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
120
+ }
47
121
 
48
- ::Thrift::Struct.generate_accessors self
49
- end
122
+ def struct_fields; FIELDS; end
50
123
 
51
- class InvalidArgumentException < ::Thrift::Exception
52
- include ::Thrift::Struct, ::Thrift::Struct_Union
53
- def initialize(message=nil)
54
- super()
55
- self.message = message
56
- end
124
+ def validate
125
+ end
57
126
 
58
- MESSAGE = 1
127
+ ::Thrift::Struct.generate_accessors self
128
+ end
59
129
 
60
- FIELDS = {
61
- MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
62
- }
130
+ class InvalidArgumentException < ::Thrift::Exception
131
+ include ::Thrift::Struct, ::Thrift::Struct_Union
132
+ def initialize(message=nil)
133
+ super()
134
+ self.message = message
135
+ end
63
136
 
64
- def struct_fields; FIELDS; end
137
+ MESSAGE = 1
65
138
 
66
- def validate
67
- end
139
+ FIELDS = {
140
+ MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
141
+ }
68
142
 
69
- ::Thrift::Struct.generate_accessors self
70
- end
143
+ def struct_fields; FIELDS; end
71
144
 
72
- class BidirectionalPPRParams
73
- include ::Thrift::Struct, ::Thrift::Struct_Union
74
- RELATIVEERROR = 1
75
- RESETPROBABILITY = 2
76
- MINPROBABILITY = 3
145
+ def validate
146
+ end
77
147
 
78
- FIELDS = {
79
- RELATIVEERROR => {:type => ::Thrift::Types::DOUBLE, :name => 'relativeError'},
80
- RESETPROBABILITY => {:type => ::Thrift::Types::DOUBLE, :name => 'resetProbability'},
81
- MINPROBABILITY => {:type => ::Thrift::Types::DOUBLE, :name => 'minProbability', :optional => true}
82
- }
148
+ ::Thrift::Struct.generate_accessors self
149
+ end
83
150
 
84
- def struct_fields; FIELDS; end
151
+ class UndefinedGraphException < ::Thrift::Exception
152
+ include ::Thrift::Struct, ::Thrift::Struct_Union
153
+ def initialize(message=nil)
154
+ super()
155
+ self.message = message
156
+ end
85
157
 
86
- def validate
87
- raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field relativeError is unset!') unless @relativeError
88
- raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field resetProbability is unset!') unless @resetProbability
89
- end
158
+ MESSAGE = 1
90
159
 
91
- ::Thrift::Struct.generate_accessors self
92
- end
160
+ FIELDS = {
161
+ MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
162
+ }
163
+
164
+ def struct_fields; FIELDS; end
165
+
166
+ def validate
167
+ end
168
+
169
+ ::Thrift::Struct.generate_accessors self
170
+ end
93
171
 
172
+ class SQLException < ::Thrift::Exception
173
+ include ::Thrift::Struct, ::Thrift::Struct_Union
174
+ def initialize(message=nil)
175
+ super()
176
+ self.message = message
177
+ end
178
+
179
+ MESSAGE = 1
180
+
181
+ FIELDS = {
182
+ MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
183
+ }
184
+
185
+ def struct_fields; FIELDS; end
186
+
187
+ def validate
188
+ end
189
+
190
+ ::Thrift::Struct.generate_accessors self
191
+ end
192
+
193
+ class UnequalListSizeException < ::Thrift::Exception
194
+ include ::Thrift::Struct, ::Thrift::Struct_Union
195
+
196
+ FIELDS = {
197
+
198
+ }
199
+
200
+ def struct_fields; FIELDS; end
201
+
202
+ def validate
203
+ end
204
+
205
+ ::Thrift::Struct.generate_accessors self
206
+ end
207
+
208
+ end
209
+ end
data/lib/tempest_db.rb CHANGED
@@ -18,8 +18,8 @@
18
18
  $:.push(File.expand_path(File.join(File.dirname(__FILE__),"gen")))
19
19
 
20
20
  require 'tempest_d_b_service'
21
- require 'tempest_db_constants'
22
- require 'tempest_db_types'
21
+ require 'tempest_constants'
22
+ require 'tempest_types'
23
23
  require 'base_thrift_client'
24
24
 
25
25
  # May also require the types and the constants for more complex services
@@ -35,10 +35,14 @@ module Teapot
35
35
  class TempestClient
36
36
  @thrift_client = nil
37
37
 
38
+ # @param [String] server
39
+ # @param [Integer] port
38
40
  def initialize(server, port)
39
41
  @thrift_client = Teapot::TempestDB::TempestThriftClient.new(server, port)
40
42
  end
41
43
 
44
+ # @param [String] json_attribute
45
+ # @return [Object]
42
46
  def TempestClient.jsonToValue(json_attribute)
43
47
  if json_attribute[0] == '"'
44
48
  json_attribute[1...-1]
@@ -54,30 +58,53 @@ module Teapot
54
58
  end
55
59
  end
56
60
 
57
- def get_multi_node_attribute(node_type, nodeIds, attribute_name)
58
- id_to_json = @thrift_client.with_retries { |executor|
59
- executor.getMultiNodeAttributeAsJSON(node_type, nodeIds, attribute_name)
61
+ # @param [Array<Teapot::TempestDB::Node>] nodes
62
+ # @param [String] attribute_name
63
+ # @return [Hash]
64
+ def get_multi_node_attribute(nodes, attribute_name)
65
+ node_to_json = @thrift_client.with_retries { |executor|
66
+ executor.getMultiNodeAttributeAsJSON(nodes, attribute_name)
60
67
  }
61
- Hash[id_to_json.map{ |k,v| [k, TempestClient.jsonToValue(v)] }]
68
+ Hash[node_to_json.map{ |k,v| [k, TempestClient.jsonToValue(v)] }]
62
69
  end
63
70
 
64
- def get_node_attribute(node_type, nodeId, attribute_name)
65
- self.get_multi_node_attribute(node_type, [nodeId], attribute_name)[nodeId]
71
+ # @param [Teapot::TempestDB::Node] node
72
+ # @param [String] attribute_name
73
+ # @return [String]
74
+ def get_node_attribute(node, attribute_name)
75
+ self.get_multi_node_attribute([node], attribute_name)[node]
66
76
  end
67
77
 
68
- def k_step_out_neighbors_filtered(edge_type, source_id, k, sql_clause: "", degree_filter: {}, alternating: true)
78
+ # @param [String] edge_type
79
+ # @param [Teapot::TempestDB::Node] source_node
80
+ # @param [Integer] k
81
+ # @param [String] sql_clause
82
+ # @param [Hash] degree_filter
83
+ # @param [Boolean] alternating
84
+ # @return [Teapot::TempestDB::Node]
85
+ def k_step_out_neighbors_filtered(edge_type, source_node, k, sql_clause: "", degree_filter: {}, alternating: true)
69
86
  @thrift_client.with_retries { |executor|
70
- executor.kStepOutNeighborsFiltered(edge_type, source_id, k, sql_clause, degree_filter, alternating)
87
+ executor.kStepOutNeighborsFiltered(edge_type, source_node, k, sql_clause, degree_filter, alternating)
71
88
  }
72
89
  end
73
90
 
74
- def k_step_in_neighbors_filtered(edge_type, source_id, k, sql_clause: "", degree_filter: {}, alternating: true)
91
+ # @param [String] edge_type
92
+ # @param [Teapot::TempestDB::Node] source_node
93
+ # @param [Integer] k
94
+ # @param [String] sql_clause
95
+ # @param [Hash] degree_filter
96
+ # @param [Boolean] alternating
97
+ # @return [Teapot::TempestDB::Node]
98
+ def k_step_in_neighbors_filtered(edge_type, source_node, k, sql_clause: "", degree_filter: {}, alternating: true)
75
99
  @thrift_client.with_retries { |executor|
76
- executor.kStepInNeighborsFiltered(edge_type, source_id, k, sql_clause, degree_filter, alternating)
100
+ executor.kStepInNeighborsFiltered(edge_type, source_node, k, sql_clause, degree_filter, alternating)
77
101
  }
78
102
  end
79
103
 
80
- # Convenience method to return the unique node id satisfying a condition
104
+ # Convenience method to return the unique node node satisfying a condition
105
+ # @param [String] node_type
106
+ # @param [String] sql_clause
107
+ # @return [Teapot::TempestDB::Node]
81
108
  def unique_node(node_type, sql_clause)
82
109
  matching_nodes = @thrift_client.with_retries { |executor|
83
110
  executor.nodes(node_type, sql_clause)
@@ -91,91 +118,164 @@ module Teapot
91
118
 
92
119
  # TODO: For methods that only need to be included (for irb auto-complete) and converted from camelCase to
93
120
  # snake_case, is there a simple way of automating this?
94
- def out_degree(edge_type, id)
121
+ # @param [String] edge_type
122
+ # @param [Teapot::TempestDB::Node] node
123
+ # @return [Integer]
124
+ def out_degree(edge_type, node)
95
125
  @thrift_client.with_retries { |executor|
96
- executor.outDegree(edge_type, id)
126
+ executor.outDegree(edge_type, node)
97
127
  }
98
128
  end
99
129
 
100
- def in_degree(edge_type, id)
130
+ # @param [String] edge_type
131
+ # @param [Teapot::TempestDB::Node] node
132
+ # @return [Integer]
133
+ def in_degree(edge_type, node)
101
134
  @thrift_client.with_retries { |executor|
102
- executor.inDegree(edge_type, id)
135
+ executor.inDegree(edge_type, node)
103
136
  }
104
137
  end
105
138
 
106
- def out_neighbors(edge_type, id)
139
+ # @param [String] edge_type
140
+ # @param [Teapot::TempestDB::Node] node
141
+ # @return [Array<Teapot::TempestDB::Node>]
142
+ def out_neighbors(edge_type, node)
107
143
  @thrift_client.with_retries { |executor|
108
- executor.outNeighbors(edge_type, id)
144
+ executor.outNeighbors(edge_type, node)
109
145
  }
110
146
  end
111
147
 
112
- def in_neighbors(edge_type, id)
148
+ # @param [String] edge_type
149
+ # @param [Teapot::TempestDB::Node] node
150
+ # @return [Array<Teapot::TempestDB::Node>]
151
+ def in_neighbors(edge_type, node)
113
152
  @thrift_client.with_retries { |executor|
114
- executor.inNeighbors(edge_type, id)
153
+ executor.inNeighbors(edge_type, node)
115
154
  }
116
155
  end
117
156
 
118
- def out_neighbor(edge_type, id, i)
157
+ # @param [String] edge_type
158
+ # @param [Teapot::TempestDB::Node] node
159
+ # @param [Integer] i
160
+ # @return [Teapot::TempestDB::Node]
161
+ def out_neighbor(edge_type, node, i)
119
162
  @thrift_client.with_retries { |executor|
120
- executor.outNeighbor(edge_type, id, i)
163
+ executor.outNeighbor(edge_type, node, i)
121
164
  }
122
165
  end
123
166
 
124
- def in_neighbor(edge_type, id, i)
167
+ # @param [String] edge_type
168
+ # @param [Teapot::TempestDB::Node] node
169
+ # @param [Integer] i
170
+ # @return [Teapot::TempestDB::Node]
171
+ def in_neighbor(edge_type, node, i)
125
172
  @thrift_client.with_retries { |executor|
126
- executor.inNeighbor(edge_type, id, i)
127
- }
128
- end
129
-
130
- def max_node_id(edge_type)
131
- @thrift_client.with_retries { |executor|
132
- executor.maxNodeId(edge_type)
173
+ executor.inNeighbor(edge_type, node, i)
133
174
  }
134
175
  end
135
176
 
177
+ # @param [String] edge_type
178
+ # @return [Integer]
136
179
  def node_count(edge_type)
137
180
  @thrift_client.with_retries { |executor|
138
181
  executor.nodeCount(edge_type)
139
182
  }
140
183
  end
141
184
 
185
+ # @param [String] edge_type
186
+ # @return [Integer]
142
187
  def edge_count(edge_type)
143
188
  @thrift_client.with_retries { |executor|
144
189
  executor.edgeCount(edge_type)
145
190
  }
146
191
  end
147
192
 
148
- def ppr_single_target(edge_type, seed_node_ids, target_node_id, bi_ppr_params)
193
+ # @param [String] edge_type
194
+ # @param [Array<Teapot::TempestDB::Node>] seed_nodes
195
+ # @param [Teapot::TempestDB::Node] target_node
196
+ # @param [Teapot::TempestDB::BidirectionalPPRParams] bi_ppr_params
197
+ # @return [Double]
198
+ def ppr_single_target(edge_type, seed_nodes, target_node, bi_ppr_params)
149
199
  @thrift_client.with_retries { |executor|
150
- executor.pprSingleTarget(edge_type, seed_node_ids, target_node_id, bi_ppr_params)
200
+ executor.pprSingleTarget(edge_type, seed_nodes, target_node, bi_ppr_params)
151
201
  }
152
202
  end
153
203
 
154
- def ppr(edge_type, seed_node_ids, seed_node_type, target_node_type, mc_ppr_params)
204
+ # @param [Teapot::TempestDB::Node] source
205
+ # @param [Array<String>] edge_types
206
+ # @param [Integer] max_size
207
+ # @return [Array<Teapot::TempestDB::Node>]
208
+ def connected_component(source, edge_types, max_size = (1 << 31) - 1)
155
209
  @thrift_client.with_retries { |executor|
156
- executor.ppr(edge_type, seed_node_ids, seed_node_type, target_node_type, mc_ppr_params)
210
+ executor.connectedComponent(source, edge_types, max_size)
157
211
  }
158
212
  end
159
213
 
214
+ # @param [String] node_type
215
+ # @param [String] sql_clause
216
+ # @return [Teapot::TempestDB::Node]
160
217
  def nodes(node_type, sql_clause)
161
218
  @thrift_client.with_retries { |executor|
162
219
  executor.nodes(node_type, sql_clause)
163
220
  }
164
221
  end
165
222
 
166
- def add_edges(edge_type, ids1, ids2)
223
+ # @param [Teapot::TempestDB::Node] node
224
+ def add_node(node)
225
+ @thrift_client.with_retries { |executor|
226
+ executor.addNode(node)
227
+ }
228
+ end
229
+
230
+ # @param [Teapot::TempestDB::Node] node
231
+ # @param [String] attribute_name
232
+ # @param [String] attribute_value
233
+ def set_node_attribute(node, attribute_name, attribute_value)
234
+ @thrift_client.with_retries { |executor|
235
+ executor.setNodeAttribute(node, attribute_name, attribute_value)
236
+ }
237
+ end
238
+
239
+ # @param [String] edge_type
240
+ # @param [Array<Teapot::TempestDB::Node>] source_nodes
241
+ # @param [Array<Teapot::TempestDB::Node>] target_nodes
242
+ def add_edges(edge_type, source_nodes, target_nodes)
167
243
  @thrift_client.with_retries { |executor|
168
- executor.addEdges(edge_type, ids1, ids2)
244
+ executor.addEdges(edge_type, source_nodes, target_nodes)
169
245
  }
170
246
  end
247
+
248
+ # @param [String] edge_type
249
+ # @param [Teapot::TempestDB::Node] source_node
250
+ # @param [Teapot::TempestDB::Node] target_node
251
+ def add_edge(edge_type, source_node, target_node)
252
+ add_edges(edge_type, [source_node], [target_node])
253
+ end
171
254
  end
172
255
  end
173
256
  end
174
257
 
258
+ # @param [String] server
259
+ # @param [Integer] port
260
+ # @return [Teapot::TempestDB::TempestClient]
175
261
  def get_tempest_client(server = 'localhost', port = 10001)
176
262
  Teapot::TempestDB::TempestClient.new(server, port)
177
263
  end
178
264
 
265
+ # @return [Hash]
179
266
  def get_empty_filter()
180
267
  Hash.new
181
268
  end
269
+
270
+ # @param [Teapot::TempestDB::Node] node
271
+ # @return [Array]
272
+ def node_to_pair(node)
273
+ [node.type, node.id]
274
+ end
275
+
276
+ # @param [String] type
277
+ # @param [String] id
278
+ # @return [Teapot::TempestDB::Node]
279
+ def make_node(type, id)
280
+ Teapot::TempestDB::Node.new({'type' => type, 'id' => id})
281
+ end