rejuicer 0.0.3 → 0.0.4

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