figure_set 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e561bc42e983722b42d4633631eebe1cb3d9ef8a7f5429867840657ed0e6ae2
4
- data.tar.gz: c81d4e8b25d38e7f4974f1d627d396421a60da2d64fd02f068d88927875f8e16
3
+ metadata.gz: 607f5983d462888fdae0e4b02ef8c2b35ce817b18497be4e0e9ab368f53e4517
4
+ data.tar.gz: 7dff01e4b5bdfd6695cc9c65d0199a94079a92e2bd751bdddf875da40c7aff5c
5
5
  SHA512:
6
- metadata.gz: f02e42c9ea2ca6e993b95d1e6fbd34f927ab862664df1f0259a0e76721e8b6c4d504f5f20efba0c50564849e7d928e384d899da8084d1432e8e5a13ccbf3f071
7
- data.tar.gz: c7ff2ea5d1961280b43faf257d766e9af8d64c567c723c3e221ab8265b6609cd714648de3050cf012708e0d2ddf86c57098bb0a4e85139dcfbd8062149b8288e
6
+ metadata.gz: 32c5187a40d3f61a7846981142bd4c28c9584730039256c7476be3de84e5fe4194e971189c8e3b8414d7a383c572befea3ada6afdc9c69a3a3a5dde6479f4682
7
+ data.tar.gz: 5732976db72898325f0965e521b8ce158723a88188d05bed982d508adc43defd9d6eaf4eb3b0a186dd6ebace9489f7b04ca49995c06ee7e586c53e431e93ac59
data/.travis.yml CHANGED
@@ -1,15 +1,14 @@
1
1
  language: ruby
2
- before_install:
3
- - gem install bundler
4
2
  before_script:
5
- - bundle update
6
- - "bundle exec rake compile"
3
+ - "bin/setup"
7
4
  script:
8
- - "bundle exec rake test"
5
+ - "bin/test"
9
6
  cache: bundler
10
7
  rvm:
11
- - 2.2.9
12
- - 2.3.6
13
- - 2.4.3
14
- - 2.5.0
8
+ - 2.3.8
9
+ - 2.4.5
10
+ - 2.5.3
11
+ - 2.6.0
12
+ matrix:
13
+ fast_finish: true
15
14
  bundler_args: --jobs 3 --retry 3
data/Manifest.txt CHANGED
@@ -1,14 +1,25 @@
1
+ .gitignore
2
+ .travis.yml
3
+ CODE_OF_CONDUCT.md
4
+ Gemfile
1
5
  History.txt
6
+ LICENSE.txt
2
7
  Manifest.txt
3
8
  README.rdoc
4
9
  Rakefile
10
+ benchmark/sample_benchmark.rb
11
+ bin/console
12
+ bin/setup
13
+ bin/test
14
+ ext/figure_set/figure_set/and.c
15
+ ext/figure_set/figure_set/array.c
16
+ ext/figure_set/figure_set/extconf.rb
17
+ ext/figure_set/figure_set/figure_set.h
18
+ ext/figure_set/figure_set/index.c
19
+ ext/figure_set/figure_set/init.c
20
+ ext/figure_set/figure_set/methods.c
21
+ ext/figure_set/figure_set/or.c
22
+ ext/figure_set/figure_set/sample.c
23
+ figure_set.gemspec
5
24
  lib/figure_set.rb
6
- ext/extconf.rb
7
- ext/figure_set.h
8
- ext/methods.c
9
- ext/init.c
10
- ext/index.c
11
- ext/and.c
12
- ext/or.c
13
- ext/array.c
14
- ext/sample.c
25
+ lib/figure_set/version.rb
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ require 'rake/testtask'
5
5
  # compile
6
6
  gemspec = eval(File.read(File.expand_path('../figure_set.gemspec', __FILE__)))
7
7
  Rake::ExtensionTask.new("figure_set", gemspec) do |ext|
8
+ ext.ext_dir = "ext/figure_set/figure_set"
8
9
  ext.lib_dir = "lib/figure_set"
9
10
  end
10
11
 
@@ -12,3 +13,13 @@ end
12
13
  Rake::TestTask.new do |t|
13
14
  t.test_files = FileList['test/**/test_*.rb']
14
15
  end
16
+
17
+ desc 'generate Manifest.txt'
18
+ task :manifest do |t|
19
+ File.open(File.expand_path("../Manifest.txt", __FILE__), "w") do |out|
20
+ gemspec.files.sort.each do |f|
21
+ out.puts(f) if File.file?(f)
22
+ end
23
+ end
24
+ puts "Generate Manifest.txt"
25
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "figure_set"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install --path .bundle
6
+ bundle exec rake compile
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/test ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle exec rake test
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,125 @@
1
+ //************************************
2
+ // and.c
3
+ //************************************
4
+
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <ruby.h>
9
+ #include "figure_set.h"
10
+
11
+ static void middel_intersection_branch_node(root_node, branch_node, branch_node, branch_node);
12
+ static void last_intersection_branch_node(root_node, branch_node, branch_node, branch_node);
13
+
14
+ static branch_node
15
+ init_and_intersection_branch_node(root_node result_set, branch_node base, branch_node other)
16
+ {
17
+ branch_node branch;
18
+
19
+ branch = (branch_node)init_branch_node();
20
+
21
+ if (base->children_type == CT_LEAF) {
22
+ last_intersection_branch_node(result_set, branch, base, other);
23
+ } else {
24
+ middel_intersection_branch_node(result_set, branch, base, other);
25
+ }
26
+
27
+ if (branch->children_size) {
28
+ branch->children_type = base->children_type;
29
+ return branch;
30
+ } else {
31
+ destroy_branch(branch);
32
+ return (branch_node)NULL;
33
+ }
34
+ }
35
+
36
+ static leaf_node
37
+ init_and_intersection_leaf_node(root_node result_set, leaf_node base, leaf_node other)
38
+ {
39
+ unsigned long data;
40
+ leaf_node leaf;
41
+
42
+ data = base->data & other->data;
43
+
44
+ if (!data) return (leaf_node)NULL;
45
+
46
+ leaf = (leaf_node)init_leaf_node(base->offset);
47
+ leaf->data = data;
48
+ result_set->size += BIT_COUNT(leaf->data);
49
+
50
+ return leaf;
51
+ }
52
+
53
+ static void
54
+ middel_intersection_branch_node(root_node result_set, branch_node branch, branch_node base, branch_node other)
55
+ {
56
+ unsigned int i, count;
57
+ branch_node middle_branch;
58
+
59
+ for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < base->children_size; i++) {
60
+ if (base->index[i]) {
61
+ count++;
62
+ if (other->index[i]) {
63
+ middle_branch = (branch_node)init_and_intersection_branch_node(result_set, (branch_node)base->index[i], (branch_node)other->index[i]);
64
+ if (middle_branch) {
65
+ branch->index[i] = (void*)middle_branch;
66
+ branch->children_size++;
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ static void
74
+ last_intersection_branch_node(root_node result_set, branch_node branch, branch_node base, branch_node other)
75
+ {
76
+ unsigned int i, count;
77
+ leaf_node leaf;
78
+
79
+ for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < base->children_size; i++) {
80
+ if (base->index[i]) {
81
+ count++;
82
+ if (other->index[i]) {
83
+ leaf = (leaf_node)init_and_intersection_leaf_node(result_set, (leaf_node)base->index[i], (leaf_node)other->index[i]);
84
+ if (leaf) {
85
+ branch->index[i] = (void*)leaf;
86
+ branch->children_size++;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ //
94
+ // intersection
95
+ //
96
+ void
97
+ intersection(root_node result_set, root_node set0, root_node set1)
98
+ {
99
+ unsigned int i, count;
100
+ root_node base, other;
101
+ branch_node branch;
102
+
103
+ if (set0->size == 0 || set1->size == 0) {
104
+ return;
105
+ } else if (set0->size > set1->size) {
106
+ base = set1;
107
+ other = set0;
108
+ } else {
109
+ base = set0;
110
+ other = set1;
111
+ }
112
+
113
+ for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < base->children_size; i++) {
114
+ if (base->index[i]) {
115
+ count++;
116
+ if (other->index[i]) {
117
+ branch = (branch_node)init_and_intersection_branch_node(result_set, (branch_node)base->index[i], (branch_node)other->index[i]);
118
+ if (branch) {
119
+ result_set->index[i] = (void*)branch;
120
+ result_set->children_size++;
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
@@ -0,0 +1,91 @@
1
+ //************************************
2
+ // array.c
3
+ //************************************
4
+
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <ruby.h>
9
+ #include "figure_set.h"
10
+
11
+ static void
12
+ search_and_get_array_at_leaf(leaf_node leaf, VALUE array)
13
+ {
14
+ unsigned long i = 0;
15
+ unsigned long x;
16
+
17
+ x = leaf->data;
18
+
19
+ while(x) {
20
+ i = BIT_COUNT((x & (-x))-1);
21
+ rb_ary_push(array, ULONG2NUM(leaf->offset + i));
22
+ x = x ^ (1UL << i);
23
+ }
24
+ }
25
+
26
+ static void
27
+ search_and_get_array(branch_node branch, VALUE array)
28
+ {
29
+ unsigned int i, count;
30
+
31
+ if (branch->children_type == CT_LEAF) {
32
+ for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
33
+ if (branch->index[i]) {
34
+ search_and_get_array_at_leaf((leaf_node)branch->index[i], array);
35
+ count++;
36
+ }
37
+ }
38
+ } else {
39
+ for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
40
+ if (branch->index[i]) {
41
+ search_and_get_array((branch_node)branch->index[i], array);
42
+ count++;
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ //
49
+ // bit count
50
+ //
51
+
52
+ // 32 bit
53
+ unsigned long
54
+ bit32_count(unsigned long x)
55
+ {
56
+ x = x - ((x >> 1UL) & 0x55555555UL);
57
+ x = (x & 0x33333333UL) + ((x >> 2UL) & 0x33333333UL);
58
+ x = (x + (x >> 4UL)) & 0x0f0f0f0fUL;
59
+ x = x + (x >> 8UL);
60
+ x = x + (x >> 16UL);
61
+ return x & 0x0000003FUL;
62
+ }
63
+
64
+ // 64 bit
65
+ unsigned long
66
+ bit64_count(unsigned long x)
67
+ {
68
+ x = x - ((x >> 1UL) & 0x5555555555555555UL);
69
+ x = (x & 0x3333333333333333UL) + ((x >> 2UL) & 0x3333333333333333UL);
70
+ x = (x & 0x0f0f0f0f0f0f0f0fUL) + ((x >> 4UL) & 0x0f0f0f0f0f0f0f0fUL);
71
+ x = (x + (x >> 8UL)) & 0x00ff00ff00ff00ffUL;
72
+ x = x + (x >> 16UL);
73
+ x = x + (x >> 32UL);
74
+ return x & 0x000000000000007FUL;
75
+ }
76
+
77
+ //
78
+ // output Array object from internal set
79
+ //
80
+ void
81
+ to_array(root_node root, VALUE array)
82
+ {
83
+ unsigned int i, count;
84
+
85
+ for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < root->children_size; i++) {
86
+ if (root->index[i]) {
87
+ search_and_get_array((branch_node)root->index[i], array);
88
+ count++;
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,2 @@
1
+ require "mkmf"
2
+ create_makefile("figure_set/figure_set")
@@ -7,18 +7,6 @@
7
7
 
8
8
  #include <math.h>
9
9
 
10
- #ifndef RUBY_19
11
- #ifndef RFLOAT_VALUE
12
- #define RFLOAT_VALUE(v) (RFLOAT(v)->value)
13
- #endif
14
- #ifndef RARRAY_LEN
15
- #define RARRAY_LEN(v) (RARRAY(v)->len)
16
- #endif
17
- #ifndef RARRAY_PTR
18
- #define RARRAY_PTR(v) (RARRAY(v)->ptr)
19
- #endif
20
- #endif
21
-
22
10
  // max children size of branch
23
11
  #define MAX_CHILDREN_SIZE_OF_BRANCH (unsigned long)16
24
12
  #define LAST_BRANCH_LEVEL (unsigned long)6
@@ -43,9 +31,6 @@ static unsigned long OFFSET_SCALE[] = {0x20000000, 0x2000000, 0x200000, 0x20000,
43
31
  #define VALID_MIN_VALUE UINT2NUM(0)
44
32
  #define VALID_MAX_VALUE UINT2NUM(0xffffffff)
45
33
 
46
- // FigureSet class object
47
- static VALUE rb_cFigureSet;
48
-
49
34
  // leaf node
50
35
  // example:
51
36
  // data = 5 # (bit is 0...0101) exist bit numbers is (2, 0)
@@ -68,78 +53,44 @@ typedef struct _branch_node {
68
53
  } *branch_node;
69
54
 
70
55
  typedef struct _root_node {
71
- unsigned char children_size;
56
+ unsigned char children_size;
72
57
  unsigned long size; // number of elements in set
73
58
  void *index[MAX_CHILDREN_SIZE_OF_ROOT_NODE]; // children pointer
74
59
  } *root_node;
75
60
 
61
+ // bit count
62
+ unsigned long bit32_count(unsigned long);
63
+ unsigned long bit64_count(unsigned long);
64
+
76
65
  // initialize
77
66
  void init_root_node(root_node);
78
- void *init_branch_node();
79
- void *init_leaf_node(unsigned long);
67
+ branch_node init_branch_node();
68
+ leaf_node init_leaf_node(unsigned long);
80
69
 
81
70
  // init_copy
82
71
  void copy_root_node(root_node, root_node);
83
- void copy_branch_node(root_node, branch_node, branch_node);
84
- void *init_and_copy_brance_node(root_node, branch_node);
85
- void *init_and_copy_leaf_node(root_node, leaf_node);
72
+ branch_node init_and_copy_brance_node(root_node, branch_node);
73
+ leaf_node init_and_copy_leaf_node(root_node, leaf_node);
74
+
75
+ // memory free
76
+ void destroy_all(root_node);
77
+ void destroy_all_branches(root_node);
78
+ void destroy_branch(branch_node);
86
79
 
87
80
  // insert element into set
88
81
  void add_num(root_node, unsigned long);
89
- unsigned int search_and_insert(branch_node, unsigned long, unsigned long, unsigned long);
90
- unsigned int search_and_insert_at_leaf(leaf_node, unsigned long);
91
82
 
92
83
  // remove element from set
93
84
  void delete_num(root_node, unsigned long);
94
- unsigned int search_and_remove(branch_node, unsigned long, unsigned long, unsigned long);
95
- unsigned int search_and_remove_at_leaf(leaf_node, unsigned long);
96
85
 
97
86
  // output Array object from internal set
98
87
  void to_array(root_node, VALUE);
99
- void search_and_get_array(branch_node, VALUE);
100
- void search_and_get_array_at_leaf(leaf_node, VALUE);
101
88
 
102
89
  // join
103
90
  void join(root_node, root_node, root_node);
104
- void middle_join_branch_node(root_node, branch_node, branch_node, branch_node);
105
- void last_join_branch_node(root_node, branch_node, branch_node, branch_node);
106
- void *init_and_join_brance_node(root_node, branch_node, branch_node);
107
- void *init_and_join_leaf_node(root_node, leaf_node, leaf_node);
108
91
 
109
92
  // intersection
110
93
  void intersection(root_node, root_node, root_node);
111
- void middel_intersection_branch_node(root_node, branch_node, branch_node, branch_node);
112
- void last_intersection_branch_node(root_node, branch_node, branch_node, branch_node);
113
- void *init_and_intersection_leaf_node(root_node, leaf_node, leaf_node);
114
- void *init_and_intersection_branch_node(root_node, branch_node, branch_node);
115
- unsigned long bit32_count(unsigned long);
116
- unsigned long bit64_count(unsigned long);
117
94
 
118
95
  // sample
119
96
  void sample(root_node, VALUE, unsigned long);
120
- void search_and_sample_array(branch_node, VALUE);
121
- void search_and_sample_array_at_leaf(leaf_node, VALUE);
122
-
123
- // memory free
124
- void destroy_all(root_node);
125
- void destroy_all_branches(root_node);
126
- void destroy_branch(branch_node);
127
-
128
- //-----------------------------------------------------------
129
- // Ruby Methods
130
- // ----------------------------------------------------------
131
-
132
- static VALUE t_allocate(VALUE);
133
- static VALUE t_initialize(int, VALUE *, VALUE);
134
- static VALUE t_initialize_copy(VALUE, VALUE);
135
- static VALUE t_add(VALUE, VALUE);
136
- static VALUE t_delete(VALUE, VALUE);
137
- static VALUE t_intersection(VALUE, VALUE);
138
- static VALUE t_union(VALUE, VALUE);
139
- static VALUE t_to_a(VALUE);
140
- static VALUE t_sample(int, VALUE *, VALUE);
141
- static VALUE t_size(VALUE);
142
- static VALUE t_empty(VALUE);
143
- static VALUE t_clear(VALUE);
144
- void Init_figure_set(void);
145
-
@@ -0,0 +1,130 @@
1
+ //************************************
2
+ // index.c
3
+ //************************************
4
+
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <ruby.h>
9
+ #include "figure_set.h"
10
+
11
+ static unsigned int search_and_insert(branch_node, unsigned long, unsigned long, unsigned long);
12
+ static unsigned int search_and_insert_at_leaf(leaf_node, unsigned long);
13
+ static unsigned int search_and_remove(branch_node, unsigned long, unsigned long, unsigned long);
14
+ static unsigned int search_and_remove_at_leaf(leaf_node, unsigned long);
15
+
16
+
17
+ static unsigned int
18
+ search_and_insert(branch_node branch, unsigned long level, unsigned long value, unsigned long original)
19
+ {
20
+ unsigned long quotient, remainder;
21
+
22
+ quotient = value / OFFSET_SCALE[level];
23
+ remainder = value % OFFSET_SCALE[level];
24
+
25
+ if(!(branch->index[quotient])) {
26
+ if(branch->children_type == CT_LEAF) {
27
+ branch->index[quotient] = init_leaf_node((unsigned long)(original / ULONG_BIT_COUNT) * ULONG_BIT_COUNT);
28
+ } else {
29
+ branch->index[quotient] = init_branch_node();
30
+ if ((level + 1) == LAST_BRANCH_LEVEL) {
31
+ ((branch_node)(branch->index[quotient]))->children_type = CT_LEAF;
32
+ }
33
+ }
34
+ branch->children_size++;
35
+ }
36
+
37
+ if (branch->children_type == CT_LEAF) {
38
+ return search_and_insert_at_leaf((leaf_node)branch->index[quotient], remainder);
39
+ } else {
40
+ return search_and_insert((branch_node)branch->index[quotient], level + 1, remainder, original);
41
+ }
42
+ }
43
+
44
+ static unsigned int
45
+ search_and_insert_at_leaf(leaf_node leaf, unsigned long value)
46
+ {
47
+ unsigned int exist_flag = 0;
48
+ unsigned long target_bit;
49
+
50
+ target_bit = 1UL << value;
51
+
52
+ if (!(leaf->data & target_bit)) {
53
+ leaf->data |= target_bit;
54
+ exist_flag = 1;
55
+ }
56
+
57
+ return exist_flag;
58
+ }
59
+
60
+ static unsigned int
61
+ search_and_remove(branch_node branch, unsigned long level, unsigned long value, unsigned long original)
62
+ {
63
+ unsigned long quotient, remainder;
64
+
65
+ quotient = value / OFFSET_SCALE[level];
66
+ remainder = value % OFFSET_SCALE[level];
67
+
68
+ if (!(branch->index[quotient])) return 0;
69
+
70
+ if (branch->children_type == CT_LEAF) {
71
+ return search_and_remove_at_leaf((leaf_node)branch->index[quotient], remainder);
72
+ } else {
73
+ return search_and_remove((branch_node)branch->index[quotient], level + 1, remainder, original);
74
+ }
75
+ }
76
+
77
+ static unsigned int
78
+ search_and_remove_at_leaf(leaf_node leaf, unsigned long value)
79
+ {
80
+ unsigned int exist_flag = 0;
81
+ unsigned long target_bit;
82
+
83
+ target_bit = 1UL << value;
84
+
85
+ if ((leaf->data & target_bit)) {
86
+ leaf->data ^= target_bit;
87
+ exist_flag = 1;
88
+ }
89
+
90
+ return exist_flag;
91
+ }
92
+
93
+ //
94
+ // insert element into set
95
+ //
96
+ void
97
+ add_num(root_node root, unsigned long value)
98
+ {
99
+ unsigned long quotient, remainder;
100
+
101
+ quotient = value / OFFSET_SCALE[0];
102
+ remainder = value % OFFSET_SCALE[0];
103
+
104
+ if(!(root->index[quotient])) {
105
+ root->index[quotient] = init_branch_node();
106
+ root->children_size++;
107
+ }
108
+
109
+ if (search_and_insert((branch_node)root->index[quotient], 1, remainder, value)) {
110
+ root->size++;
111
+ }
112
+ }
113
+
114
+ //
115
+ // remove element from set
116
+ //
117
+ void
118
+ delete_num(root_node root, unsigned long value)
119
+ {
120
+ unsigned long quotient, remainder;
121
+
122
+ quotient = value / OFFSET_SCALE[0];
123
+ remainder = value % OFFSET_SCALE[0];
124
+
125
+ if (!(root->index[quotient])) return;
126
+
127
+ if (search_and_remove((branch_node)root->index[quotient], 1, remainder, value)) {
128
+ root->size--;
129
+ }
130
+ }