rejuicer 0.0.3 → 0.0.4
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.
- data/Manifest.txt +7 -2
- data/README.rdoc +7 -0
- data/ext/extconf.rb +1 -1
- data/ext/rejuicer_set/and.c +97 -0
- data/ext/rejuicer_set/index.c +119 -0
- data/ext/rejuicer_set/init.c +183 -0
- data/ext/rejuicer_set/main.c +213 -0
- data/ext/rejuicer_set/or.c +109 -0
- data/ext/{rejuicer_set.h → rejuicer_set/rejuicer_set.h} +24 -1
- data/ext/rejuicer_set/util.c +79 -0
- data/lib/rejuicer.rb +36 -7
- metadata +10 -5
- data/ext/rejuicer_set.c +0 -468
data/Manifest.txt
CHANGED
@@ -4,5 +4,10 @@ README.rdoc
|
|
4
4
|
Rakefile
|
5
5
|
lib/rejuicer.rb
|
6
6
|
ext/extconf.rb
|
7
|
-
ext/rejuicer_set.h
|
8
|
-
ext/rejuicer_set.c
|
7
|
+
ext/rejuicer_set/rejuicer_set.h
|
8
|
+
ext/rejuicer_set/main.c
|
9
|
+
ext/rejuicer_set/init.c
|
10
|
+
ext/rejuicer_set/index.c
|
11
|
+
ext/rejuicer_set/and.c
|
12
|
+
ext/rejuicer_set/or.c
|
13
|
+
ext/rejuicer_set/util.c
|
data/README.rdoc
CHANGED
@@ -14,6 +14,13 @@
|
|
14
14
|
|
15
15
|
index.set(mother)
|
16
16
|
|
17
|
+
=== Add to Index
|
18
|
+
num = 20000
|
19
|
+
inst = work.new(num, num % 2 == 0, num % 3, num % 5)
|
20
|
+
index.add(inst)
|
21
|
+
=== Remove from Index
|
22
|
+
index.delete(inst)
|
23
|
+
|
17
24
|
== Search
|
18
25
|
index.search(:odd_flag => false) #=> [1,3,5,7,9...,9997,9999]
|
19
26
|
index.search(:remainder_3 => 2, :remainder_5 => 4) #=> [14,29,44,59,...,9974,9989]
|
data/ext/extconf.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require "mkmf"
|
2
|
-
create_makefile("rejuicer_set")
|
2
|
+
create_makefile("rejuicer_set/rejuicer_set", "rejuicer_set")
|
@@ -0,0 +1,97 @@
|
|
1
|
+
//************************************
|
2
|
+
// rejuicer.c
|
3
|
+
//
|
4
|
+
// Tsukasa OISHI
|
5
|
+
//
|
6
|
+
// 2010/03/17
|
7
|
+
//************************************
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <ruby.h>
|
13
|
+
#include "rejuicer_set.h"
|
14
|
+
|
15
|
+
//
|
16
|
+
// intersection
|
17
|
+
//
|
18
|
+
void intersection(root_node ret_set, root_node set0, root_node set1)
|
19
|
+
{
|
20
|
+
int i, count;
|
21
|
+
root_node base, other;
|
22
|
+
|
23
|
+
if (set0->size == 0 || set1->size == 0) {
|
24
|
+
return;
|
25
|
+
} else if (set0->size > set1->size) {
|
26
|
+
base = set1;
|
27
|
+
other = set0;
|
28
|
+
} else {
|
29
|
+
base = set0;
|
30
|
+
other = set1;
|
31
|
+
}
|
32
|
+
|
33
|
+
for (i = 0, count = 0; i < ROOT_NODE_SIZE || count < base->children_size; i++) {
|
34
|
+
if (base->index[i]) {
|
35
|
+
count++;
|
36
|
+
if (other->index[i]) {
|
37
|
+
ret_set->index[i] = (branch_node)init_and_intersection_branch_node(ret_set, (branch_node)base->index[i], (branch_node)other->index[i]);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
void intersection_branch_node(root_node root, branch_node ret_set, branch_node base, branch_node other)
|
44
|
+
{
|
45
|
+
if (ret_set->level == LAST_BRANCH_LEVEL) {
|
46
|
+
last_intersection_branch_node(root, ret_set, base, other);
|
47
|
+
} else {
|
48
|
+
middel_intersection_branch_node(root, ret_set, base, other);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
void middel_intersection_branch_node(root_node root, branch_node ret_set, branch_node base, branch_node other)
|
53
|
+
{
|
54
|
+
int i, count;
|
55
|
+
|
56
|
+
for (i = 0, count = 0; i < BRANCH_NODE_SIZE || count < base->children_size; i++) {
|
57
|
+
if (base->index[i]) {
|
58
|
+
count++;
|
59
|
+
if (other->index[i]) {
|
60
|
+
ret_set->index[i] = (branch_node)init_and_intersection_branch_node(root, (branch_node)base->index[i], (branch_node)other->index[i]);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
void last_intersection_branch_node(root_node root, branch_node ret_set, branch_node base, branch_node other)
|
67
|
+
{
|
68
|
+
int i, count;
|
69
|
+
|
70
|
+
for (i = 0, count = 0; i < BRANCH_NODE_SIZE || count < base->children_size; i++) {
|
71
|
+
if (base->index[i]) {
|
72
|
+
count++;
|
73
|
+
if (other->index[i]) {
|
74
|
+
ret_set->index[i] = init_leaf_node2(((leaf_node)base->index[i])->num);
|
75
|
+
intersection_leaf_node(root, (leaf_node)ret_set->index[i], (leaf_node)base->index[i], (leaf_node)other->index[i]);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
|
82
|
+
void intersection_leaf_node(root_node root, leaf_node ret_set, leaf_node base, leaf_node other)
|
83
|
+
{
|
84
|
+
ret_set->data = base->data & other->data;
|
85
|
+
root->size += bit_count(ret_set->data);
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
void *init_and_intersection_branch_node(root_node root, branch_node base, branch_node other)
|
90
|
+
{
|
91
|
+
branch_node ret;
|
92
|
+
|
93
|
+
ret = init_branch_node2(base->level, base->num);
|
94
|
+
intersection_branch_node(root, ret, base, other);
|
95
|
+
|
96
|
+
return ret;
|
97
|
+
}
|
@@ -0,0 +1,119 @@
|
|
1
|
+
//************************************
|
2
|
+
// rejuicer.c
|
3
|
+
//
|
4
|
+
// Tsukasa OISHI
|
5
|
+
//
|
6
|
+
// 2010/03/17
|
7
|
+
//************************************
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <ruby.h>
|
13
|
+
#include "rejuicer_set.h"
|
14
|
+
|
15
|
+
//
|
16
|
+
// insert element into set
|
17
|
+
//
|
18
|
+
void add_num(root_node root, unsigned int value)
|
19
|
+
{
|
20
|
+
unsigned int quotient, remainder;
|
21
|
+
|
22
|
+
quotient = value / INDEX_PER_SIZE[0];
|
23
|
+
remainder = value % INDEX_PER_SIZE[0];
|
24
|
+
|
25
|
+
if(!(root->index[quotient])) {
|
26
|
+
root->index[quotient] = init_branch_node(1, quotient);
|
27
|
+
root->children_size++;
|
28
|
+
}
|
29
|
+
|
30
|
+
if (search_and_insert((branch_node)root->index[quotient], 1, remainder, value)) {
|
31
|
+
root->size++;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
int search_and_insert(branch_node branch, int level, unsigned int value, unsigned int original)
|
36
|
+
{
|
37
|
+
unsigned int quotient, remainder;
|
38
|
+
|
39
|
+
quotient = value / INDEX_PER_SIZE[level];
|
40
|
+
remainder = value % INDEX_PER_SIZE[level];
|
41
|
+
|
42
|
+
if(!(branch->index[quotient])) {
|
43
|
+
branch->children_size++;
|
44
|
+
if(level == LAST_BRANCH_LEVEL) {
|
45
|
+
branch->index[quotient] = init_leaf_node(original);
|
46
|
+
} else {
|
47
|
+
branch->index[quotient] = init_branch_node(level + 1, original);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
if (level == LAST_BRANCH_LEVEL) {
|
52
|
+
return search_and_insert_at_leaf((leaf_node)branch->index[quotient], remainder);
|
53
|
+
} else {
|
54
|
+
return search_and_insert((branch_node)branch->index[quotient], level + 1, remainder, original);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
int search_and_insert_at_leaf(leaf_node leaf, unsigned int value)
|
59
|
+
{
|
60
|
+
int exist_flag = 0;
|
61
|
+
unsigned int target_bit;
|
62
|
+
|
63
|
+
target_bit = 1 << value;
|
64
|
+
|
65
|
+
if (!(leaf->data & target_bit)) {
|
66
|
+
leaf->data |= target_bit;
|
67
|
+
exist_flag = 1;
|
68
|
+
}
|
69
|
+
|
70
|
+
return exist_flag;
|
71
|
+
}
|
72
|
+
|
73
|
+
//
|
74
|
+
// remove element from set
|
75
|
+
//
|
76
|
+
void delete_num(root_node root, unsigned int value)
|
77
|
+
{
|
78
|
+
unsigned int quotient, remainder;
|
79
|
+
|
80
|
+
quotient = value / INDEX_PER_SIZE[0];
|
81
|
+
remainder = value % INDEX_PER_SIZE[0];
|
82
|
+
|
83
|
+
if (!(root->index[quotient])) return;
|
84
|
+
|
85
|
+
if (search_and_remove((branch_node)root->index[quotient], 1, remainder, value)) {
|
86
|
+
root->size--;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
int search_and_remove(branch_node branch, int level, unsigned int value, unsigned int original)
|
91
|
+
{
|
92
|
+
unsigned int quotient, remainder, result;
|
93
|
+
|
94
|
+
quotient = value / INDEX_PER_SIZE[level];
|
95
|
+
remainder = value % INDEX_PER_SIZE[level];
|
96
|
+
|
97
|
+
if (!(branch->index[quotient])) return;
|
98
|
+
|
99
|
+
if (level == LAST_BRANCH_LEVEL) {
|
100
|
+
return search_and_remove_at_leaf((leaf_node)branch->index[quotient], remainder);
|
101
|
+
} else {
|
102
|
+
return search_and_remove((branch_node)branch->index[quotient], level + 1, remainder, original);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
int search_and_remove_at_leaf(leaf_node leaf, unsigned int value)
|
107
|
+
{
|
108
|
+
int exist_flag = 0;
|
109
|
+
unsigned int target_bit;
|
110
|
+
|
111
|
+
target_bit = 1 << value;
|
112
|
+
|
113
|
+
if ((leaf->data & target_bit)) {
|
114
|
+
leaf->data ^= target_bit;
|
115
|
+
exist_flag = 1;
|
116
|
+
}
|
117
|
+
|
118
|
+
return exist_flag;
|
119
|
+
}
|
@@ -0,0 +1,183 @@
|
|
1
|
+
//************************************
|
2
|
+
// rejuicer.c
|
3
|
+
//
|
4
|
+
// Tsukasa OISHI
|
5
|
+
//
|
6
|
+
// 2010/03/17
|
7
|
+
//************************************
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <ruby.h>
|
13
|
+
#include "rejuicer_set.h"
|
14
|
+
|
15
|
+
//
|
16
|
+
// initialize
|
17
|
+
//
|
18
|
+
void init_root_node(root_node root)
|
19
|
+
{
|
20
|
+
int i;
|
21
|
+
|
22
|
+
for(i = 0; i < ROOT_NODE_SIZE; i++) {
|
23
|
+
root->index[i] = (void*)NULL;
|
24
|
+
}
|
25
|
+
root->size = 0;
|
26
|
+
root->children_size = 0;
|
27
|
+
}
|
28
|
+
|
29
|
+
void *init_branch_node(int level, unsigned int value)
|
30
|
+
{
|
31
|
+
return init_branch_node2(level, (value / INDEX_PER_SIZE[level - 1]));
|
32
|
+
}
|
33
|
+
|
34
|
+
void *init_branch_node2(int level, unsigned int num)
|
35
|
+
{
|
36
|
+
int i;
|
37
|
+
branch_node branch;
|
38
|
+
|
39
|
+
if (!(branch = (branch_node)malloc(sizeof(struct _branch_node)))) {
|
40
|
+
rb_raise(rb_eStandardError, "memory is not enough");
|
41
|
+
}
|
42
|
+
|
43
|
+
for(i = 0; i < BRANCH_NODE_SIZE; i++) {
|
44
|
+
branch->index[i] = (void*)NULL;
|
45
|
+
}
|
46
|
+
|
47
|
+
branch->level = level;
|
48
|
+
branch->num = num;
|
49
|
+
branch->children_size = 0;
|
50
|
+
|
51
|
+
return (void*)branch;
|
52
|
+
}
|
53
|
+
|
54
|
+
void *init_leaf_node(unsigned int value)
|
55
|
+
{
|
56
|
+
return init_leaf_node2(value / INDEX_PER_SIZE[LAST_BRANCH_LEVEL]);
|
57
|
+
}
|
58
|
+
|
59
|
+
void *init_leaf_node2(unsigned int num)
|
60
|
+
{
|
61
|
+
leaf_node leaf;
|
62
|
+
|
63
|
+
if(!(leaf = (leaf_node)malloc(sizeof(struct _leaf_node)))) {
|
64
|
+
rb_raise(rb_eStandardError, "memory is not enough");
|
65
|
+
}
|
66
|
+
|
67
|
+
leaf->num = num;
|
68
|
+
leaf->data = 0;
|
69
|
+
|
70
|
+
return (void*)leaf;
|
71
|
+
}
|
72
|
+
|
73
|
+
//
|
74
|
+
// initialize copy
|
75
|
+
//
|
76
|
+
void copy_root_node(root_node root, root_node orig)
|
77
|
+
{
|
78
|
+
int i, count;
|
79
|
+
|
80
|
+
root->children_size = orig->children_size;
|
81
|
+
|
82
|
+
for (i = 0, count = 0; i < ROOT_NODE_SIZE || count < orig->children_size; i++) {
|
83
|
+
if (orig->index[i]) {
|
84
|
+
root->index[i] = (branch_node)init_and_copy_brance_node(root, (branch_node)orig->index[i]);
|
85
|
+
count++;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
void copy_branch_node(root_node root, branch_node branch, branch_node orig)
|
91
|
+
{
|
92
|
+
int i, count;
|
93
|
+
|
94
|
+
branch->num = orig->num;
|
95
|
+
branch->level = orig->level;
|
96
|
+
branch->children_size = orig->children_size;
|
97
|
+
|
98
|
+
if (orig->level == LAST_BRANCH_LEVEL) {
|
99
|
+
for(i = 0, count = 0; i < BRANCH_NODE_SIZE || count < orig->children_size; i++) {
|
100
|
+
if (orig->index[i]) {
|
101
|
+
branch->index[i] = (leaf_node)init_and_copy_leaf_node(root, (leaf_node)orig->index[i]);
|
102
|
+
count++;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
} else {
|
106
|
+
for(i = 0, count = 0; i < BRANCH_NODE_SIZE || count < orig->children_size; i++) {
|
107
|
+
if (orig->index[i]) {
|
108
|
+
branch->index[i] = (branch_node)init_and_copy_brance_node(root, (branch_node)orig->index[i]);
|
109
|
+
count++;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
void *init_and_copy_brance_node(root_node root, branch_node orig)
|
116
|
+
{
|
117
|
+
branch_node ret;
|
118
|
+
|
119
|
+
ret = init_branch_node2(orig->level, orig->num);
|
120
|
+
copy_branch_node(root, ret, orig);
|
121
|
+
|
122
|
+
return ret;
|
123
|
+
}
|
124
|
+
|
125
|
+
void *init_and_copy_leaf_node(root_node root, leaf_node orig)
|
126
|
+
{
|
127
|
+
leaf_node ret;
|
128
|
+
|
129
|
+
ret = init_leaf_node2(orig->num);
|
130
|
+
ret->data = orig->data;
|
131
|
+
root->size += bit_count(ret->data);
|
132
|
+
|
133
|
+
return ret;
|
134
|
+
}
|
135
|
+
|
136
|
+
//
|
137
|
+
// memory free
|
138
|
+
//
|
139
|
+
void destroy_all(root_node root)
|
140
|
+
{
|
141
|
+
destroy_all_branches(root);
|
142
|
+
free(root);
|
143
|
+
}
|
144
|
+
|
145
|
+
void destroy_all_branches(root_node root)
|
146
|
+
{
|
147
|
+
int i, count;
|
148
|
+
|
149
|
+
for(i = 0, count = 0; i < ROOT_NODE_SIZE || count < root->children_size; i++) {
|
150
|
+
if (root->index[i]) {
|
151
|
+
destroy_branch((branch_node)root->index[i]);
|
152
|
+
root->index[i] = NULL;
|
153
|
+
count++;
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
root->size = 0;
|
158
|
+
root->children_size = 0;
|
159
|
+
}
|
160
|
+
|
161
|
+
void destroy_branch(branch_node branch)
|
162
|
+
{
|
163
|
+
int i, count;
|
164
|
+
|
165
|
+
if (branch->level == LAST_BRANCH_LEVEL) {
|
166
|
+
for(i = 0, count = 0; i < BRANCH_NODE_SIZE || count < branch->children_size; i++) {
|
167
|
+
if (branch->index[i]) {
|
168
|
+
free((leaf_node)branch->index[i]);
|
169
|
+
branch->index[i] = NULL;
|
170
|
+
count++;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
} else {
|
174
|
+
for(i = 0, count = 0; i < BRANCH_NODE_SIZE || count < branch->children_size; i++) {
|
175
|
+
if (branch->index[i]) {
|
176
|
+
destroy_branch((branch_node)branch->index[i]);
|
177
|
+
branch->index[i] = NULL;
|
178
|
+
count++;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
free(branch);
|
183
|
+
}
|
@@ -0,0 +1,213 @@
|
|
1
|
+
//************************************
|
2
|
+
// rejuicer.c
|
3
|
+
//
|
4
|
+
// Tsukasa OISHI
|
5
|
+
//
|
6
|
+
// 2010/03/17
|
7
|
+
//************************************
|
8
|
+
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <ruby.h>
|
13
|
+
#include "rejuicer_set.h"
|
14
|
+
|
15
|
+
//-----------------------------------------------------------
|
16
|
+
// Ruby Methods
|
17
|
+
// ----------------------------------------------------------
|
18
|
+
|
19
|
+
/**
|
20
|
+
* allocate
|
21
|
+
**/
|
22
|
+
static VALUE t_allocate(VALUE klass)
|
23
|
+
{
|
24
|
+
VALUE obj;
|
25
|
+
root_node root;
|
26
|
+
|
27
|
+
obj = Data_Make_Struct(klass, struct _root_node, NULL, destroy_all, root);
|
28
|
+
init_root_node(root);
|
29
|
+
|
30
|
+
return obj;
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* initialize
|
35
|
+
**/
|
36
|
+
static VALUE t_initialize(int argc, VALUE *argv, VALUE self)
|
37
|
+
{
|
38
|
+
VALUE num;
|
39
|
+
root_node root;
|
40
|
+
|
41
|
+
Data_Get_Struct(self, struct _root_node, root);
|
42
|
+
if (argc == 1) {
|
43
|
+
while((num = rb_ary_shift(argv[0])) != Qnil) {
|
44
|
+
add_num(root, NUM2UINT(num));
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
return self;
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* initialize_copy
|
53
|
+
**/
|
54
|
+
static VALUE t_initialize_copy(VALUE self, VALUE orig)
|
55
|
+
{
|
56
|
+
root_node root, orig_set;
|
57
|
+
|
58
|
+
Data_Get_Struct(self, struct _root_node, root);
|
59
|
+
Data_Get_Struct(orig, struct _root_node, orig_set);
|
60
|
+
copy_root_node(root, orig_set);
|
61
|
+
|
62
|
+
return self;
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
* add
|
67
|
+
**/
|
68
|
+
static VALUE t_add(VALUE self, VALUE value)
|
69
|
+
{
|
70
|
+
root_node root;
|
71
|
+
unsigned int num;
|
72
|
+
|
73
|
+
Data_Get_Struct(self, struct _root_node, root);
|
74
|
+
add_num(root, NUM2UINT(value));
|
75
|
+
|
76
|
+
return self;
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* delete
|
81
|
+
**/
|
82
|
+
static VALUE t_delete(VALUE self, VALUE value)
|
83
|
+
{
|
84
|
+
root_node root;
|
85
|
+
unsigned int num;
|
86
|
+
|
87
|
+
Data_Get_Struct(self, struct _root_node, root);
|
88
|
+
delete_num(root, NUM2UINT(value));
|
89
|
+
|
90
|
+
return self;
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* intersection
|
95
|
+
**/
|
96
|
+
static VALUE t_intersection(VALUE self, VALUE other)
|
97
|
+
{
|
98
|
+
root_node set0, set1, ret_set;
|
99
|
+
VALUE ret;
|
100
|
+
|
101
|
+
ret = Data_Make_Struct(rb_cRejuicerSet, struct _root_node, NULL, destroy_all, ret_set);
|
102
|
+
init_root_node(ret_set);
|
103
|
+
|
104
|
+
Data_Get_Struct(self, struct _root_node, set0);
|
105
|
+
Data_Get_Struct(other, struct _root_node, set1);
|
106
|
+
|
107
|
+
intersection(ret_set, set0, set1);
|
108
|
+
|
109
|
+
return ret;
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* union
|
114
|
+
**/
|
115
|
+
static VALUE t_union(VALUE self, VALUE other)
|
116
|
+
{
|
117
|
+
root_node set0, set1, ret_set;
|
118
|
+
VALUE ret;
|
119
|
+
|
120
|
+
ret = Data_Make_Struct(rb_cRejuicerSet, struct _root_node, NULL, destroy_all, ret_set);
|
121
|
+
init_root_node(ret_set);
|
122
|
+
|
123
|
+
Data_Get_Struct(self, struct _root_node, set0);
|
124
|
+
Data_Get_Struct(other, struct _root_node, set1);
|
125
|
+
|
126
|
+
join(ret_set, set0, set1);
|
127
|
+
|
128
|
+
return ret;
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* to_a
|
133
|
+
**/
|
134
|
+
static VALUE t_to_a(VALUE self)
|
135
|
+
{
|
136
|
+
int i;
|
137
|
+
root_node root;
|
138
|
+
VALUE array;
|
139
|
+
|
140
|
+
Data_Get_Struct(self, struct _root_node, root);
|
141
|
+
array = rb_ary_new2(root->size);
|
142
|
+
|
143
|
+
to_array(root, array);
|
144
|
+
|
145
|
+
return array;
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* size
|
150
|
+
**/
|
151
|
+
static VALUE t_size(VALUE self)
|
152
|
+
{
|
153
|
+
root_node root;
|
154
|
+
|
155
|
+
Data_Get_Struct(self, struct _root_node, root);
|
156
|
+
|
157
|
+
return INT2NUM(root->size);
|
158
|
+
}
|
159
|
+
|
160
|
+
/**
|
161
|
+
* empty?
|
162
|
+
**/
|
163
|
+
static VALUE t_empty(VALUE self)
|
164
|
+
{
|
165
|
+
root_node root;
|
166
|
+
|
167
|
+
Data_Get_Struct(self, struct _root_node, root);
|
168
|
+
|
169
|
+
if (root->size == 0) {
|
170
|
+
return Qtrue;
|
171
|
+
} else {
|
172
|
+
return Qfalse;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* cler
|
178
|
+
**/
|
179
|
+
static VALUE t_clear(VALUE self)
|
180
|
+
{
|
181
|
+
root_node root;
|
182
|
+
|
183
|
+
Data_Get_Struct(self, struct _root_node, root);
|
184
|
+
|
185
|
+
if (root->size) {
|
186
|
+
destroy_all_branches(root);
|
187
|
+
}
|
188
|
+
|
189
|
+
return self;
|
190
|
+
}
|
191
|
+
|
192
|
+
|
193
|
+
/**
|
194
|
+
* define class
|
195
|
+
**/
|
196
|
+
void Init_rejuicer_set(void) {
|
197
|
+
rb_cRejuicerSet = rb_define_class("RejuicerSet", rb_cObject);
|
198
|
+
rb_define_alloc_func(rb_cRejuicerSet, t_allocate);
|
199
|
+
rb_define_private_method(rb_cRejuicerSet, "initialize", t_initialize, -1);
|
200
|
+
rb_define_method(rb_cRejuicerSet, "initialize_copy", t_initialize_copy, 1);
|
201
|
+
rb_define_method(rb_cRejuicerSet, "add", t_add, 1);
|
202
|
+
rb_define_method(rb_cRejuicerSet, "delete", t_delete, 1);
|
203
|
+
rb_define_method(rb_cRejuicerSet, "intersection", t_intersection, 1);
|
204
|
+
rb_define_method(rb_cRejuicerSet, "union", t_union, 1);
|
205
|
+
rb_define_method(rb_cRejuicerSet, "to_a", t_to_a, 0);
|
206
|
+
rb_define_method(rb_cRejuicerSet, "size", t_size, 0);
|
207
|
+
rb_define_method(rb_cRejuicerSet, "empty?", t_empty, 0);
|
208
|
+
rb_define_method(rb_cRejuicerSet, "clear", t_clear, 0);
|
209
|
+
rb_define_alias(rb_cRejuicerSet, "<<", "add");
|
210
|
+
rb_define_alias(rb_cRejuicerSet, "&", "intersection");
|
211
|
+
rb_define_alias(rb_cRejuicerSet, "|", "union");
|
212
|
+
rb_define_alias(rb_cRejuicerSet, "length", "size");
|
213
|
+
}
|