text_rank 1.2.5 → 1.2.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8578660270e5eb59c1bd9cfc7b3a22d10ac953cc6672073b368bbf20464dc3f3
4
- data.tar.gz: 6043c2eea693623b65f2dffc0ad2be1ae5bb0f1be57dcbbcb8ad871c4260a63b
3
+ metadata.gz: ea53630f7c00d0731b2a190c8c8775b7f433557611b85b17eae8c0989bfac108
4
+ data.tar.gz: 184389405a3ddbf216290f2a9bc806c5c70484dea4b677a89f089bfb0054f161
5
5
  SHA512:
6
- metadata.gz: 73acab105c3f6dbee7b7c49bd383f41b0da192d1c67b56c9813f7ad1f32c70790b7a99f334bccd3104573e78f39cd5400f0ea066bf2f776da7f6c7083b4d9df2
7
- data.tar.gz: c51e2861b1aaa21ce91c783d3528815b66c343d8299564a50e69ad0887b14d06908d54626fbd01ed8508f52cd8d893433d3c91f5eec6f8a6feff4bbc077c8a17
6
+ metadata.gz: 4cce8fa0323a59e52bb1b0f220f93c8dfdb68b795f7027e1f871c563d331083dbe4803b3176b14f15d2de5dc7c9d533af8104e125149ff05af397b88f02df6bb
7
+ data.tar.gz: 07efa700bbc61c56ca440a0d241a576a531f4caa4f26c48b7e8a938f19cdadf5d59d1d6bcf46d3cfc43ca4c5a4ada865ef2dbb4e6d376abefed283c6a410c719
data/.gitignore CHANGED
@@ -8,3 +8,7 @@
8
8
  /pkg/
9
9
  /spec/reports/
10
10
  /tmp/
11
+
12
+
13
+ *.bundle
14
+ *.so
data/.travis.yml CHANGED
@@ -9,6 +9,7 @@ before_script:
9
9
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
10
10
  - chmod +x ./cc-test-reporter
11
11
  - ./cc-test-reporter before-build
12
+ - bundle exec rake compile
12
13
  script:
13
14
  - bundle exec rspec
14
15
  after_script:
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
2
3
  require "rspec/core/rake_task"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
@@ -10,3 +11,7 @@ RDoc::Task.new do |rdoc|
10
11
  rdoc.main = "README.md"
11
12
  rdoc.rdoc_files.include("README.md", "lib/**/*.rb")
12
13
  end
14
+
15
+ Rake::ExtensionTask.new('text_rank') do |ext|
16
+ ext.lib_dir = 'lib/text_rank'
17
+ end
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+
3
+ create_makefile('text_rank/text_rank')
@@ -0,0 +1,296 @@
1
+ #include <ruby.h>
2
+ #include <math.h>
3
+ #include <page_rank_sparse_native.h>
4
+
5
+ const size_t NODE_LIST_SIZE = sizeof(NodeListStruct);
6
+ const size_t EDGE_LIST_SIZE = sizeof(EdgeListStruct);
7
+ const size_t NODE_SIZE = sizeof(NodeStruct);
8
+ const size_t EDGE_SIZE = sizeof(EdgeStruct);
9
+ const size_t GRAPH_SIZE = sizeof(GraphStruct);
10
+
11
+ static const rb_data_type_t graph_typed_data = {
12
+ "PageRank/SparseNative/Graph",
13
+ { 0, free_graph, },
14
+ 0, 0,
15
+ RUBY_TYPED_FREE_IMMEDIATELY,
16
+ };
17
+
18
+
19
+ //////////////////////////////////////////////////////////////////////////////////////
20
+
21
+ void Init_sparse_native() {
22
+ VALUE PageRankModule, SparseNativeClass;
23
+
24
+ PageRankModule = rb_const_get(rb_cObject, rb_intern("PageRank"));
25
+ SparseNativeClass = rb_const_get(PageRankModule, rb_intern("SparseNative"));
26
+
27
+ rb_define_alloc_func(SparseNativeClass, sparse_native_allocate);
28
+ rb_define_private_method(SparseNativeClass, "_add_edge", sparse_native_add_edge, 3);
29
+ rb_define_private_method(SparseNativeClass, "_calculate", sparse_native_calculate, 3);
30
+ }
31
+
32
+ VALUE sparse_native_allocate(VALUE self) {
33
+ Graph g = malloc(GRAPH_SIZE);
34
+ //st_table *tmp, *node_lookup;
35
+
36
+ const struct st_hash_type *objhash = rb_hash_tbl(rb_hash_new())->type;
37
+
38
+ g->node_count = 0;
39
+ g->nodes = NULL;
40
+ g->dangling_nodes = NULL;
41
+ g->node_lookup = st_init_table_with_size(objhash, 0);
42
+
43
+ return TypedData_Wrap_Struct(self, &graph_typed_data, g);
44
+ }
45
+
46
+ VALUE sparse_native_add_edge(VALUE self, VALUE source, VALUE dest, VALUE weight) {
47
+ Graph g;
48
+
49
+ TypedData_Get_Struct(self, GraphStruct, &graph_typed_data, g);
50
+ add_edge_with_labels(g, source, dest, NUM2DBL(weight));
51
+ return Qnil;
52
+ }
53
+
54
+ VALUE sparse_native_calculate(VALUE self, VALUE max_iterations, VALUE damping, VALUE tolerance) {
55
+ Graph g;
56
+ VALUE ranks;
57
+
58
+ TypedData_Get_Struct(self, GraphStruct, &graph_typed_data, g);
59
+ calculate(g, FIX2INT(max_iterations), NUM2DBL(damping), NUM2DBL(tolerance));
60
+
61
+ ranks = rb_hash_new();
62
+ sort_and_normalize_ranks(g, rb_hash_dset, ranks);
63
+ return ranks;
64
+ }
65
+
66
+ void rb_hash_dset(VALUE hash, VALUE key, double value) {
67
+ rb_hash_aset(hash, key, DBL2NUM(value));
68
+ }
69
+
70
+ //////////////////////////////////////////////////////////////////////////////////////
71
+
72
+ void free_graph(void *data) {
73
+ Graph g = (Graph)data;
74
+ free_node_list(g->nodes, free_node);
75
+ free_node_list(g->dangling_nodes, NULL);
76
+ free(g->node_lookup);
77
+ free(g);
78
+ }
79
+
80
+ void free_node(Node n) {
81
+ free_edge_list(n->source_edges, free_edge);
82
+ free(n);
83
+ }
84
+
85
+ void free_node_list(NodeList nodes, void (*free_item)(Node)) {
86
+ NodeList tmp;
87
+ while (nodes != NULL) {
88
+ tmp = nodes;
89
+ nodes = nodes->next;
90
+ if (free_item) {
91
+ free_item(tmp->node);
92
+ }
93
+ free(tmp);
94
+ }
95
+ }
96
+
97
+ void free_edge(Edge e) {
98
+ // Assume source node was allocated elsewhere and will be free'd elsewhere
99
+ free(e);
100
+ }
101
+
102
+ void free_edge_list(EdgeList edges, void (*free_item)(Edge)) {
103
+ EdgeList tmp;
104
+ while (edges != NULL) {
105
+ tmp = edges;
106
+ edges = edges->next;
107
+ if (free_item) {
108
+ free_item(tmp->edge);
109
+ }
110
+ free(tmp);
111
+ }
112
+ }
113
+
114
+ //////////////////////////////////////////////////////////////////////////////////////
115
+
116
+ Node add_node(Graph g, VALUE label) {
117
+ NodeList tmp = malloc(NODE_LIST_SIZE);
118
+
119
+ tmp->node = malloc(NODE_SIZE);
120
+ tmp->node->label = label;
121
+ tmp->node->source_edges = NULL;
122
+ tmp->node->rank = 0.0;
123
+ tmp->node->prev_rank = 0.0;
124
+ tmp->node->outbound_weight_total = 0.0;
125
+
126
+ tmp->next = g->nodes;
127
+ g->nodes = tmp;
128
+ g->node_count += 1;
129
+
130
+ return tmp->node;
131
+ }
132
+
133
+ Node add_dangling_node(Graph g, Node n) {
134
+ NodeList tmp = malloc(NODE_LIST_SIZE);
135
+
136
+ tmp->node = n;
137
+ tmp->next = g->dangling_nodes;
138
+ g->dangling_nodes = tmp;
139
+
140
+ return n;
141
+ }
142
+
143
+ Edge add_edge(Node source, Node destination, double weight) {
144
+ EdgeList tmp = malloc(EDGE_LIST_SIZE);
145
+
146
+ tmp->edge = malloc(EDGE_SIZE);
147
+ tmp->edge->source = source;
148
+ tmp->edge->weight = weight;
149
+
150
+ tmp->next = destination->source_edges;
151
+ destination->source_edges = tmp;
152
+ source->outbound_weight_total += weight;
153
+
154
+ return tmp->edge;
155
+ }
156
+
157
+ Edge add_edge_with_labels(Graph g, VALUE source_label, VALUE dest_label, double weight) {
158
+ Node source, dest;
159
+
160
+ source = lookup_node(g, source_label);
161
+ dest = lookup_node(g, dest_label);
162
+
163
+ return add_edge(source, dest, weight);
164
+ }
165
+
166
+ Node lookup_node(Graph g, VALUE label) {
167
+ Node n;
168
+
169
+ if (!st_lookup(g->node_lookup, (st_data_t)label, (st_data_t *)&n)) {
170
+ n = add_node(g, label);
171
+ st_add_direct(g->node_lookup, (st_data_t)label, (st_data_t)n);
172
+ }
173
+ return n;
174
+ }
175
+
176
+ //////////////////////////////////////////////////////////////////////////////////////
177
+
178
+ void calculate_start(Graph g) {
179
+ NodeList nodes;
180
+ Node source, destination;
181
+ EdgeList edges;
182
+ Edge e;
183
+
184
+ for (nodes = g->nodes; nodes != NULL; nodes = nodes->next) {
185
+ destination = nodes->node;
186
+
187
+ // If there is no outband, this is a "dangling" node
188
+ if (destination->outbound_weight_total == 0.0) {
189
+ add_dangling_node(g, destination);
190
+ }
191
+
192
+ // Normalize all source edge weights
193
+ for (edges = destination->source_edges; edges != NULL; edges = edges->next) {
194
+ e = edges->edge;
195
+ source = e->source;
196
+ e->weight = e->weight / source->outbound_weight_total;
197
+ }
198
+
199
+ // Set the initial rank
200
+ destination->prev_rank = 0;
201
+ destination->rank = 1.0 / g->node_count;
202
+ }
203
+ }
204
+
205
+ void calculate_step(Graph g, double damping) {
206
+ NodeList nodes, dangling_nodes;
207
+ Node source, destination;
208
+ EdgeList edges;
209
+ Edge e;
210
+ double sum;
211
+
212
+ // Set prev rank to rank for all nodes
213
+ for (nodes = g->nodes; nodes != NULL; nodes = nodes->next) {
214
+ destination = nodes->node;
215
+ destination->prev_rank = destination->rank;
216
+ }
217
+
218
+ // Re-destribute the rankings according to weight
219
+ for (nodes = g->nodes; nodes != NULL; nodes = nodes->next) {
220
+ destination = nodes->node;
221
+ sum = 0.0;
222
+ for (edges = destination->source_edges; edges != NULL; edges = edges->next) {
223
+ e = edges->edge;
224
+ source = e->source;
225
+ sum += source->prev_rank * e->weight;
226
+ }
227
+ for (dangling_nodes = g->dangling_nodes; dangling_nodes != NULL; dangling_nodes = dangling_nodes->next) {
228
+ source = dangling_nodes->node;
229
+ sum += source->prev_rank / g->node_count;
230
+ }
231
+ destination->rank = damping * sum + (1 - damping) / g->node_count;
232
+ }
233
+ }
234
+
235
+ // Calculate the Euclidean distance from prev_rank to rank across all nodes
236
+ double prev_distance(Graph g) {
237
+ NodeList nodes;
238
+ Node n;
239
+ double rank_diff, sum_squares = 0.0;
240
+
241
+ for (nodes = g->nodes; nodes != NULL; nodes = nodes->next) {
242
+ n = nodes->node;
243
+ rank_diff = n->prev_rank - n->rank;
244
+ sum_squares += rank_diff * rank_diff;
245
+ }
246
+
247
+ return sqrt(sum_squares);
248
+ }
249
+
250
+ void calculate(Graph g, int max_iterations, double damping, double tolerance) {
251
+ calculate_start(g);
252
+
253
+ while (max_iterations != 0) { // If negative one, allow to go without limit
254
+ calculate_step(g, damping);
255
+ if (prev_distance(g) < tolerance) {
256
+ break;
257
+ }
258
+ max_iterations--;
259
+ }
260
+ }
261
+
262
+ int node_compare(const void *v1, const void *v2) {
263
+ double rank1, rank2, cmp;
264
+
265
+ rank1 = (*(Node *)v1)->rank;
266
+ rank2 = (*(Node *)v2)->rank;
267
+ cmp = rank2 - rank1; // Decreasing order
268
+ if (cmp < 0) return -1;
269
+ if (cmp > 0) return 1;
270
+ return 0;
271
+ }
272
+
273
+ void sort_and_normalize_ranks(Graph g, void (*callback)(VALUE, VALUE, double), VALUE callback_arg) {
274
+ NodeList nodes;
275
+ Node n;
276
+ double sum = 0.0;
277
+ unsigned long i;
278
+ Node *tmp;
279
+
280
+ i = g->node_count;
281
+ tmp = malloc(g->node_count * sizeof(Node));
282
+ for (nodes = g->nodes; nodes != NULL; nodes = nodes->next) {
283
+ n = nodes->node;
284
+ tmp[--i] = n;
285
+ sum += n->rank;
286
+ }
287
+
288
+ qsort(tmp, g->node_count, sizeof(Node), node_compare);
289
+
290
+ for (i = 0; i < g->node_count; i++) {
291
+ n = tmp[i];
292
+ callback(callback_arg, n->label, n->rank / sum);
293
+ }
294
+
295
+ free(tmp);
296
+ }
@@ -0,0 +1,93 @@
1
+ #ifndef PAGE_RANK_SPARSE_NATIVE_H
2
+ #define PAGE_RANK_SPARSE_NATIVE_H
3
+
4
+ #include <ruby.h>
5
+
6
+ struct NodeListStruct;
7
+ typedef struct NodeListStruct* NodeList;
8
+
9
+ typedef struct NodeListStruct {
10
+ struct NodeStruct *node;
11
+ struct NodeListStruct *next;
12
+ } NodeListStruct;
13
+
14
+ //////////////////////////////////////////////////////////////////////////////////////
15
+
16
+ struct EdgeListStruct;
17
+ typedef struct EdgeListStruct* EdgeList;
18
+
19
+ typedef struct EdgeListStruct {
20
+ struct EdgeStruct *edge;
21
+ struct EdgeListStruct *next;
22
+ } EdgeListStruct;
23
+
24
+ //////////////////////////////////////////////////////////////////////////////////////
25
+
26
+ struct NodeStruct;
27
+ typedef struct NodeStruct* Node;
28
+
29
+ typedef struct NodeStruct {
30
+ EdgeList source_edges;
31
+ VALUE label;
32
+ double prev_rank;
33
+ double rank;
34
+ double outbound_weight_total;
35
+ } NodeStruct;
36
+
37
+ //////////////////////////////////////////////////////////////////////////////////////
38
+
39
+ struct EdgeStruct;
40
+ typedef struct EdgeStruct* Edge;
41
+
42
+ typedef struct EdgeStruct {
43
+ Node source;
44
+ double weight;
45
+ } EdgeStruct;
46
+
47
+ //////////////////////////////////////////////////////////////////////////////////////
48
+
49
+ struct GraphStruct;
50
+ typedef struct GraphStruct* Graph;
51
+
52
+ typedef struct GraphStruct {
53
+ unsigned long node_count;
54
+ NodeList nodes;
55
+ NodeList dangling_nodes;
56
+ st_table *node_lookup;
57
+ } GraphStruct;
58
+
59
+ //////////////////////////////////////////////////////////////////////////////////////
60
+
61
+ void free_graph(void *data);
62
+ void free_node(Node n);
63
+ void free_node_list(NodeList nodes, void (*free_item)(Node));
64
+ void free_edge(Edge e);
65
+ void free_edge_list(EdgeList edges, void (*free_item)(Edge));
66
+
67
+ //////////////////////////////////////////////////////////////////////////////////////
68
+
69
+ Node add_node(Graph g, VALUE label);
70
+ Node add_dangling_node(Graph g, Node n);
71
+ Edge add_edge(Node source, Node destination, double weight);
72
+ Edge add_edge_with_labels(Graph g, VALUE source_label, VALUE dest_label, double weight);
73
+ Node lookup_node(Graph g, VALUE label);
74
+
75
+ //////////////////////////////////////////////////////////////////////////////////////
76
+
77
+ void calculate_start(Graph g);
78
+ void calculate_step(Graph g, double damping);
79
+ double prev_distance(Graph g);
80
+ void calculate(Graph g, int max_iterations, double damping, double tolerance);
81
+ int node_compare(const void *v1, const void *v2);
82
+ void sort_and_normalize_ranks(Graph g, void (*callback)(VALUE, VALUE, double), VALUE callback_arg);
83
+
84
+ //////////////////////////////////////////////////////////////////////////////////////
85
+
86
+ void Init_sparse_native();
87
+ VALUE sparse_native_allocate(VALUE self);
88
+ VALUE sparse_native_add_edge(VALUE self, VALUE source, VALUE dest, VALUE weight);
89
+ VALUE sparse_native_calculate(VALUE self, VALUE max_iterations, VALUE damping, VALUE tolerance);
90
+ VALUE sorted_and_normalized_ranks(Graph g);
91
+ void rb_hash_dset(VALUE hash, VALUE key, double value);
92
+
93
+ #endif
@@ -0,0 +1,5 @@
1
+ #include <page_rank_sparse_native.h>
2
+
3
+ void Init_text_rank() {
4
+ Init_sparse_native();
5
+ }
data/lib/page_rank.rb CHANGED
@@ -17,16 +17,17 @@ require 'set'
17
17
  ##
18
18
  module PageRank
19
19
 
20
- autoload :Base, 'page_rank/base'
21
- autoload :Dense, 'page_rank/dense'
22
- autoload :Sparse, 'page_rank/sparse'
20
+ autoload :Base, 'page_rank/base'
21
+ autoload :Dense, 'page_rank/dense'
22
+ autoload :Sparse, 'page_rank/sparse'
23
+ autoload :SparseNative, 'page_rank/sparse_native'
23
24
 
24
25
  # @option options [Symbol] :strategy PageRank strategy to use (either :sparse or :dense)
25
26
  # @option options [Float] :damping The probability of following the graph vs. randomly choosing a new node
26
27
  # @option options [Float] :tolerance The desired accuracy of the results
27
28
  # @return [PageRank::Base]
28
29
  def self.new(strategy: :sparse, **options)
29
- const_get(strategy.to_s.capitalize).new(**options)
30
+ const_get(strategy.to_s.split('_').map(&:capitalize).join).new(**options)
30
31
  end
31
32
 
32
33
  # Convenience method to quickly calculate PageRank. In the calling block, graph edges can be added.
@@ -7,6 +7,8 @@ module PageRank
7
7
  ##
8
8
  class Base
9
9
 
10
+ attr_reader :damping, :tolerance
11
+
10
12
  # @param (see #damping=)
11
13
  # @param (see #tolerance=)
12
14
  def initialize(damping: nil, tolerance: nil, **_)
@@ -48,7 +50,7 @@ module PageRank
48
50
 
49
51
  prev_ranks = ranks
50
52
  ranks = calculate_step(ranks)
51
- break if distance(ranks, prev_ranks) < @tolerance
53
+ break if distance(ranks, prev_ranks) < tolerance
52
54
 
53
55
  max_iterations -= 1
54
56
  end
@@ -79,7 +79,7 @@ module PageRank
79
79
  total = total_out_weights[source_idx]
80
80
  if total
81
81
  w = @out_links[source_idx][dest_idx] || 0.0
82
- @damping * w / total + (1 - @damping) / node_count.to_f
82
+ damping * w / total + (1 - damping) / node_count.to_f
83
83
  else
84
84
  1.0 / node_count.to_f
85
85
  end
@@ -68,7 +68,7 @@ module PageRank
68
68
  @dangling_nodes.each do |source|
69
69
  sum += ranks[source] / node_count.to_f
70
70
  end
71
- new_ranks[dest] = @damping * sum + (1 - @damping) / node_count
71
+ new_ranks[dest] = damping * sum + (1 - damping) / node_count
72
72
  end
73
73
  end
74
74
 
@@ -0,0 +1,21 @@
1
+ module PageRank
2
+ class SparseNative < Base
3
+
4
+ #require 'page_rank/sparse_native.so'
5
+
6
+ # @param (see Base#add)
7
+ # @param weight [Float] Optional weight for the graph edge
8
+ # @return (see Base#add)
9
+ def add(source, dest, weight: 1.0)
10
+ _add_edge(source, dest, weight) unless source == dest
11
+ end
12
+
13
+ # Perform the PageRank calculation
14
+ # @param max_iterations [Fixnum] Maximum number of PageRank iterations to perform (or -1 for no max)
15
+ # @return [Hash<Object, Float>] of nodes with rank
16
+ def calculate(max_iterations: -1, **_)
17
+ _calculate(max_iterations, damping, tolerance)
18
+ end
19
+
20
+ end
21
+ end
data/lib/text_rank.rb CHANGED
@@ -40,3 +40,5 @@ module TextRank
40
40
  end
41
41
 
42
42
  end
43
+
44
+ require 'text_rank/text_rank'
@@ -1,6 +1,6 @@
1
1
  module TextRank
2
2
 
3
3
  # Current gem version
4
- VERSION = '1.2.5'
4
+ VERSION = '1.2.9'
5
5
 
6
6
  end
data/text_rank.gemspec CHANGED
@@ -16,10 +16,12 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
17
  spec.bindir = 'exe'
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.extensions = ['ext/text_rank/extconf.rb']
19
20
  spec.require_paths = ['lib']
20
21
 
21
22
  spec.add_development_dependency 'bundler'
22
23
  spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rake-compiler'
23
25
  spec.add_development_dependency 'rspec'
24
26
  spec.add_development_dependency 'rubocop'
25
27
  spec.add_development_dependency 'simplecov', '~> 0.17.0' # 0.18 not supported by code climate
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: text_rank
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - David McCullars
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-27 00:00:00.000000000 Z
11
+ date: 2021-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +141,8 @@ description: Implementation of TextRank solution to ranked keyword extraction.
127
141
  email:
128
142
  - david.mccullars@gmail.com
129
143
  executables: []
130
- extensions: []
144
+ extensions:
145
+ - ext/text_rank/extconf.rb
131
146
  extra_rdoc_files: []
132
147
  files:
133
148
  - ".codeclimate.yml"
@@ -143,10 +158,15 @@ files:
143
158
  - Rakefile
144
159
  - bin/console
145
160
  - bin/setup
161
+ - ext/text_rank/extconf.rb
162
+ - ext/text_rank/page_rank_sparse_native.c
163
+ - ext/text_rank/page_rank_sparse_native.h
164
+ - ext/text_rank/text_rank.c
146
165
  - lib/page_rank.rb
147
166
  - lib/page_rank/base.rb
148
167
  - lib/page_rank/dense.rb
149
168
  - lib/page_rank/sparse.rb
169
+ - lib/page_rank/sparse_native.rb
150
170
  - lib/text_rank.rb
151
171
  - lib/text_rank/char_filter.rb
152
172
  - lib/text_rank/char_filter/ascii_folding.rb