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.
@@ -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
@@ -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]
@@ -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
+ }