figure_set 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }