digital_trees_and_sets 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,156 @@
1
+ // A non existently thin (inline) layer to sanitize judy calling interface
2
+
3
+ // working with the assumption that NULL is not a valid value
4
+
5
+ // Function are get/set/delete , first/next/bycount/length , clear/mem (memtotal?)
6
+
7
+ // Indexes are VALUE's
8
+ // All numbers also VALUES (though not converted) (rembering that a value is short for unsigned long int)
9
+ // Both Judy1 and JudyL go as Tree, as typecheking is done the layer above and their void* anyway
10
+ // Interface uses Tree* for consitency on all functions
11
+ // Using Qfalse which actualy is NULL (as we use VALUE not pointers)
12
+
13
+ #include "judy.h"
14
+ #include "ruby.h"
15
+
16
+ static inline int basic_type(VALUE x){
17
+ return (x == Qnil || x == Qtrue || x == Qfalse || FIXNUM_P(x) || SYMBOL_P(x) ) ;
18
+ }
19
+ static inline void check_index_basic(VALUE i){ // for judy_hash/set
20
+ if(!basic_type(i)) rb_raise(rb_eArgError ,"Key must be int or symbol, not %s" , RSTRING_PTR(rb_funcall(i,rb_intern("to_s"),0)));
21
+ }
22
+
23
+ typedef struct {
24
+ VALUE count ;
25
+ void* judy ;
26
+ } tree_object;
27
+
28
+ typedef Pvoid_t Tree;
29
+
30
+ static inline int judy_set_has(Tree* set , VALUE index){
31
+ return Judy1Test(*set, index , PJE0) ;
32
+ }
33
+ static inline VALUE judy_set_set(Tree* set , VALUE index){
34
+ int was;
35
+ was = Judy1Set(set, index , PJE0) ;
36
+ return was ? Qtrue : Qfalse ;
37
+ }
38
+ static inline VALUE judy_set_delete(Tree* set , VALUE index){
39
+ int was;
40
+ was = Judy1Unset(set, index , PJE0) ;
41
+ return was ? Qtrue : Qfalse ;
42
+ }
43
+
44
+ static inline VALUE judy_set_first_index(Tree* set){
45
+ VALUE index = 0 ;
46
+ VALUE continu = 0 ;
47
+ continu = Judy1First(*set, &index, PJE0);
48
+ return continu ? index : Qfalse ;
49
+ }
50
+ static inline VALUE judy_set_next_index(Tree* set , VALUE index){
51
+ VALUE continu = 0 ;
52
+ continu = Judy1Next(*set, &index, PJE0);
53
+ return continu ? index : Qfalse ;
54
+ }
55
+ static inline VALUE judy_set_last_index(Tree* set){
56
+ VALUE index = -1 ;
57
+ VALUE continu = 0 ;
58
+ continu = Judy1Last(*set, &index, PJE0);
59
+ return continu ? index : Qfalse ;
60
+ }
61
+ static inline VALUE judy_set_prev_index(Tree* set , VALUE index){
62
+ VALUE continu = 0 ;
63
+ continu = Judy1Prev(*set, &index, PJE0);
64
+ return continu ? index : Qfalse ;
65
+ }
66
+ static inline VALUE judy_set_at_count(Tree* set , VALUE at){
67
+ VALUE index = Qfalse ;
68
+ VALUE continu;
69
+ continu = Judy1ByCount(*set, NUM2INT(at) , &index, PJE0);
70
+ return continu ? index : Qfalse ;
71
+ }
72
+
73
+ static inline VALUE judy_set_length(Tree* set){
74
+ VALUE c;
75
+ c = Judy1Count(*set, 0 , -1 , PJE0) ;
76
+ return UINT2NUM(c) ;
77
+ }
78
+ static inline void judy_set_clear(Tree* set){
79
+ Judy1FreeArray(set , PJE0) ;
80
+ }
81
+ static inline VALUE judy_set_mem(Tree* set){
82
+ VALUE c;
83
+ c = Judy1MemUsed(*set) ;
84
+ return UINT2NUM(c) ;
85
+ }
86
+
87
+ static inline tree_object* judy_array_at_index(Tree* array , VALUE index){
88
+ tree_object** val;
89
+ val = (tree_object**)JudyLGet(*array, index , PJE0) ;
90
+ if(val == NULL) return NULL;
91
+ return *val;
92
+ }
93
+ static inline tree_object* judy_array_set(Tree* array , VALUE index , tree_object* value ){
94
+ tree_object* was = NULL ;
95
+ tree_object** there;
96
+ there = (tree_object**)JudyLIns(array, index , PJE0) ;
97
+ if( *there != NULL ) was = *there ;
98
+ *there = value ;
99
+ return was ;
100
+ }
101
+ static inline tree_object* judy_array_delete(Tree* array , VALUE index){
102
+ tree_object* was ;
103
+ was = judy_array_at_index(array , index);
104
+ JudyLDel(array, index , PJE0) ;
105
+ return was ;
106
+ }
107
+
108
+ static inline VALUE judy_array_first_index(Tree* array){
109
+ VALUE index = 0;
110
+ VALUE* here;
111
+ here = (VALUE*)JudyLFirst(*array, &index, PJE0);
112
+ if(here == NULL) index = Qfalse ;
113
+ return index;
114
+ }
115
+ static inline VALUE judy_array_next_index(Tree* array , VALUE i){
116
+ VALUE index = i;
117
+ VALUE* here;
118
+ here = (VALUE*)JudyLNext(*array, &index, PJE0);
119
+ if(here == NULL) index = Qfalse ;
120
+ return index;
121
+ }
122
+ static inline VALUE judy_array_last_index(Tree* array){
123
+ VALUE index = -1;
124
+ VALUE* here;
125
+ here = (VALUE*)JudyLLast(*array, &index, PJE0);
126
+ if(here == NULL) index = Qfalse ;
127
+ return index;
128
+ }
129
+ static inline VALUE judy_array_prev_index(Tree* array , VALUE i){
130
+ VALUE index = i;
131
+ VALUE* here;
132
+ here = (VALUE*)JudyLPrev(*array, &index, PJE0);
133
+ if(here == NULL) index = Qfalse ;
134
+ return index;
135
+ }
136
+ static inline tree_object* judy_array_at_count(Tree* array , VALUE at){
137
+ tree_object** val;
138
+ VALUE index;
139
+ val = (tree_object**)JudyLByCount(*array, NUM2INT(at) , &index, PJE0);
140
+ if(val == NULL ) return NULL;
141
+ return *val;
142
+ }
143
+
144
+ static inline VALUE judy_array_length(Tree* array){
145
+ VALUE c;
146
+ c = JudyLCount(*array, 0 , -1 , PJE0) ;
147
+ return UINT2NUM(c) ;
148
+ }
149
+ static inline void judy_array_clear(Tree* array){
150
+ JudyLFreeArray(array , PJE0) ;
151
+ }
152
+ static inline VALUE judy_array_mem(Tree* array){
153
+ VALUE c;
154
+ c = JudyLMemUsed(*array) ;
155
+ return UINT2NUM(c) ;
156
+ }
@@ -0,0 +1,227 @@
1
+ /************************************************
2
+ Author : Torsten Rueger , Copyright 2002-20011
3
+ License: GPL v.2 see LICENSE
4
+ ************************************************/
5
+ #include "judy_compat.h"
6
+
7
+ // The class JudyHash is a RubyHash replacement. At least to the degree that the implementation is complete.
8
+ // Also it really only takes int and symbol as keys
9
+
10
+
11
+ typedef Tree JudyHash; // JudyHash == pcvoid_t
12
+
13
+ // Get_Hash converts from the ruby world to c judy-pointers
14
+ // Basically all functions available from ruby start with a call to Get_Hash
15
+ JudyHash * Get_Hash(VALUE obj) {
16
+ tree_object* object ;//= DATA_PTR(obj);
17
+ Check_Type(obj , T_DATA);
18
+ object = DATA_PTR(obj);
19
+ // assert( JudyHash == object->class) ;
20
+ return (JudyHash*) &(object->judy) ;
21
+ }
22
+
23
+ VALUE ruby_JudyHash_clear(VALUE self) {
24
+ JudyHash *p_hash = Get_Hash(self) ;
25
+ JudyLFreeArray( p_hash, PJE0);
26
+ return self;
27
+ }
28
+
29
+ void gc_mark_hash( tree_object* hash){
30
+ VALUE value , index ;
31
+ if(hash == NULL) return ;
32
+ index = judy_array_first_index(&(hash->judy));
33
+ while (index != Qfalse) {
34
+ value = (VALUE) judy_array_at_index(&(hash->judy) , index);
35
+ rb_gc_mark(value );
36
+ index = judy_array_next_index(&(hash->judy), index);
37
+ }
38
+ }
39
+ void gc_free_hash( tree_object* p_hash){
40
+ if(p_hash == NULL) return;
41
+ JudyLFreeArray( &(p_hash->judy), PJE0);
42
+ free(p_hash);
43
+ }
44
+
45
+ VALUE ruby_JudyHash_allocate(VALUE self) {
46
+ tree_object* tree = malloc( sizeof(tree_object) ) ;
47
+ tree->judy = NULL;
48
+ return Data_Wrap_Struct(self, gc_mark_hash, gc_free_hash, tree);
49
+ }
50
+
51
+ VALUE ruby_JudyHash_getitem(VALUE self , VALUE index) {
52
+ VALUE val;
53
+ JudyHash *p_hash ;
54
+ if( index == Qnil ) return Qnil ;
55
+ p_hash = Get_Hash(self);
56
+ check_index_basic(index);
57
+ val = (VALUE)judy_array_at_index(p_hash, index);
58
+ return (val == 0) ? Qnil : val;
59
+ }
60
+
61
+ VALUE ruby_JudyHash_has_key(VALUE self , VALUE index) {
62
+ JudyHash *p_hash ;
63
+ VALUE val;
64
+ if( index == Qnil ) return Qnil ;
65
+ p_hash = Get_Hash(self) ;
66
+ check_index_basic(index);
67
+ if(!p_hash) return Qfalse;
68
+ val = (VALUE)judy_array_at_index(p_hash, index);
69
+ return (val == 0) ? Qfalse : Qtrue;
70
+ }
71
+
72
+ VALUE ruby_JudyHash_delete(VALUE self , VALUE index) {
73
+ JudyHash *p_hash = Get_Hash(self) ;
74
+ tree_object * was;
75
+ check_index_basic(index);
76
+ if( index == Qnil ) return Qfalse ;
77
+ was = judy_array_delete(p_hash , index);
78
+ return (was == NULL) ? Qfalse : Qtrue ;
79
+ }
80
+
81
+ VALUE ruby_JudyHash_setitem(VALUE self , VALUE index , VALUE value ) {
82
+ JudyHash *p_hash = Get_Hash(self) ;
83
+ tree_object *was;
84
+ check_index_basic(index);
85
+ if( index == Qnil ) return Qnil ;
86
+ was = judy_array_set(p_hash , index , (tree_object*)value);
87
+ return value;
88
+ }
89
+
90
+ VALUE ruby_JudyHash_length(VALUE self) {
91
+ JudyHash *p_hash = Get_Hash(self) ;
92
+ return judy_array_length(p_hash);
93
+ }
94
+
95
+ VALUE ruby_JudyHash_each_key(VALUE self) {
96
+ JudyHash *p_hash = Get_Hash(self) ;
97
+ VALUE index = judy_array_first_index(p_hash);
98
+ while (index != Qfalse) {
99
+ rb_yield(index);
100
+ index = judy_array_next_index(p_hash, index);
101
+ }
102
+ return self;
103
+ }
104
+
105
+ VALUE ruby_JudyHash_keys(VALUE self) {
106
+ JudyHash *p_hash = Get_Hash(self) ;
107
+ VALUE index = judy_array_first_index(p_hash);
108
+ VALUE array = rb_ary_new();
109
+ while (index != Qfalse) {
110
+ rb_ary_push(array , (VALUE)index);
111
+ index = judy_array_next_index(p_hash, index);
112
+ }
113
+ return array;
114
+ }
115
+
116
+ VALUE ruby_JudyHash_each(VALUE self) {
117
+ JudyHash *p_hash = Get_Hash(self) ;
118
+ VALUE index = Qfalse;
119
+ VALUE value = Qnil;
120
+ if(p_hash == NULL) return self;
121
+ index = judy_array_first_index(p_hash);
122
+ while (index != Qfalse) {
123
+ value = (VALUE) judy_array_at_index(p_hash , index);
124
+ rb_yield_values(2 , index , value );
125
+ index = judy_array_next_index(p_hash, index);
126
+ }
127
+ return self;
128
+ }
129
+
130
+ VALUE ruby_JudyHash_empty(VALUE self) {
131
+ JudyHash *p_hash = Get_Hash(self) ;
132
+ int c;
133
+ if( ! p_hash ) return Qtrue;
134
+ c = JudyLCount(*p_hash, 0 , -1 , PJE0) ;
135
+ return (0 == c) ? Qtrue : Qfalse ;
136
+ }
137
+
138
+ VALUE ruby_JudyHash_by_count(VALUE self, VALUE num) {
139
+ JudyHash *p_hash = Get_Hash(self) ;
140
+ VALUE val;
141
+ check_index_basic(num);
142
+ val = (VALUE)judy_array_at_count(p_hash, num);
143
+ return (val == 0) ? Qnil : val;
144
+ }
145
+
146
+ VALUE ruby_JudyHash_mem_used(VALUE self) {
147
+ JudyHash *p_hash = Get_Hash(self) ;
148
+ return judy_array_mem(p_hash);
149
+ }
150
+
151
+ VALUE ruby_JudyHash_first_index(VALUE self) {
152
+ JudyHash *p_hash = Get_Hash(self) ;
153
+ VALUE val = (VALUE)judy_array_first_index(p_hash);
154
+ return (val == 0) ? Qnil : val;
155
+ }
156
+
157
+ VALUE ruby_JudyHash_next_index(VALUE self, VALUE in) {
158
+ JudyHash *p_hash = Get_Hash(self) ;
159
+ VALUE val;
160
+ check_index_basic(in);
161
+ val = (VALUE)judy_array_next_index(p_hash, in);
162
+ return (val == 0) ? Qnil : val;
163
+ }
164
+
165
+ VALUE ruby_JudyHash_last_index(VALUE self) {
166
+ JudyHash *p_hash = Get_Hash(self) ;
167
+ VALUE val = (VALUE)judy_array_last_index(p_hash);
168
+ return (val == 0) ? Qnil : val;
169
+ }
170
+ VALUE ruby_JudyHash_prev_index(VALUE self, VALUE in) {
171
+ JudyHash *p_hash = Get_Hash(self) ;
172
+ VALUE val;
173
+ check_index_basic(in);
174
+ val = (VALUE)judy_array_prev_index(p_hash, in);
175
+ return (val == 0) ? Qnil : val;
176
+ }
177
+
178
+ VALUE ruby_JudyHash_includeq(VALUE self, VALUE dat) {
179
+ JudyHash *p_hash = Get_Hash(self) ;
180
+ VALUE index = judy_array_first_index(p_hash);
181
+ VALUE value = Qnil;
182
+ while (index != Qfalse) {
183
+ value = (VALUE) judy_array_at_index(p_hash , index);
184
+ if( dat == value ) return index;
185
+ index = judy_array_next_index(p_hash, index);
186
+ }
187
+ return Qfalse;
188
+ }
189
+
190
+ VALUE ruby_Hash_mem_used(VALUE hash) {
191
+ if (!RHASH(hash)->ntbl ) return Qnil;
192
+ return UINT2NUM(st_memsize(RHASH(hash)->ntbl));
193
+ }
194
+
195
+ extern void Init_JudySet(void);
196
+
197
+ /* Ruby calls this when it loads the module. Define all public functions
198
+ and initialize variables */
199
+ void Init_digital_trees_and_sets(){
200
+ VALUE cJudyHash_klass = rb_define_class("JudyHash", rb_cObject);
201
+ rb_include_module(cJudyHash_klass, rb_eval_string("Enumerable"));
202
+ rb_define_singleton_method(cJudyHash_klass, "new", ruby_JudyHash_allocate, 0);
203
+ rb_define_method(cJudyHash_klass, "[]=", ruby_JudyHash_setitem, 2);
204
+ rb_define_method(cJudyHash_klass, "set", ruby_JudyHash_setitem, 2);
205
+ rb_define_method(cJudyHash_klass, "delete", ruby_JudyHash_delete, 1);
206
+ rb_define_method(cJudyHash_klass, "get", ruby_JudyHash_getitem, 1);
207
+ rb_define_method(cJudyHash_klass, "[]", ruby_JudyHash_getitem, 1);
208
+ rb_define_method(cJudyHash_klass, "do_get", ruby_JudyHash_getitem, 1);
209
+ rb_define_method(cJudyHash_klass, "length", ruby_JudyHash_length, 0);
210
+ rb_define_method(cJudyHash_klass, "empty?", ruby_JudyHash_empty, 0);
211
+ rb_define_method(cJudyHash_klass, "count", ruby_JudyHash_length, 0);
212
+ rb_define_method(cJudyHash_klass, "each_key", ruby_JudyHash_each_key, 0);
213
+ rb_define_method(cJudyHash_klass, "each", ruby_JudyHash_each, 0);
214
+ rb_define_method(cJudyHash_klass, "keys", ruby_JudyHash_keys, 0);
215
+ rb_define_method(cJudyHash_klass, "by_count", ruby_JudyHash_by_count, 1);
216
+ rb_define_method(cJudyHash_klass, "mem_used", ruby_JudyHash_mem_used, 0);
217
+ rb_define_method(cJudyHash_klass, "first_index", ruby_JudyHash_first_index, 0);
218
+ rb_define_method(cJudyHash_klass, "next_index", ruby_JudyHash_next_index, 1);
219
+ rb_define_method(cJudyHash_klass, "last_index", ruby_JudyHash_last_index, 0);
220
+ rb_define_method(cJudyHash_klass, "clear", ruby_JudyHash_clear, 0);
221
+ rb_define_method(cJudyHash_klass, "include?", ruby_JudyHash_includeq, 1);
222
+ rb_define_method(cJudyHash_klass, "has_key?", ruby_JudyHash_has_key, 1);
223
+ // for testing
224
+ rb_define_method(rb_cHash, "mem_used", ruby_Hash_mem_used, 0);
225
+
226
+ Init_JudySet();
227
+ }
@@ -0,0 +1,146 @@
1
+ /************************************************
2
+ Author : Torsten Rueger , Copyright 2002-20011
3
+ License: GPL v.2 see LICENSE
4
+ ************************************************/
5
+ #include "judy_compat.h"
6
+
7
+ // The class JudySet is a Ruby Api to a judy set. It only takes ints and symbols though
8
+
9
+ typedef Tree JudySet; // JudySet == pcvoid_t
10
+
11
+ static inline JudySet * Get_Set(VALUE obj) {
12
+ tree_object* object;
13
+ Check_Type(obj, T_DATA);
14
+ object = DATA_PTR(obj);
15
+ return (JudySet*) &(object->judy) ;
16
+ }
17
+
18
+ void gc_free_set(tree_object* set){
19
+ judy_set_clear(&(set->judy));
20
+ free(set);
21
+ }
22
+
23
+ VALUE ruby_JudySet_allocate(VALUE self) {
24
+ tree_object* set = malloc( sizeof(tree_object) ) ;
25
+ set->judy = NULL;
26
+ return Data_Wrap_Struct(self, NULL, gc_free_set, set); // NULL means no marking
27
+ }
28
+
29
+ VALUE ruby_JudySet_delete(VALUE self , VALUE index) {
30
+ JudySet *p_set;
31
+ if( index == Qnil ) return Qnil ;
32
+ p_set = Get_Set(self) ;
33
+ check_index_basic(index);
34
+ return judy_set_delete(p_set , index) ;
35
+ }
36
+
37
+ VALUE ruby_JudySet_set(VALUE self , VALUE index , VALUE value ) {
38
+ JudySet *p_set;
39
+ if( index == Qnil ) return Qnil ;
40
+ if( value == Qnil || value == Qfalse ) return ruby_JudySet_delete(self , index) ;
41
+ p_set = Get_Set(self) ;
42
+ check_index_basic(index);
43
+ return judy_set_set(p_set , index);
44
+ }
45
+
46
+ VALUE ruby_JudySet_add(VALUE self , VALUE index ) {
47
+ JudySet *p_set;
48
+ if( index == Qnil ) return Qnil ;
49
+ p_set = Get_Set(self) ;
50
+ check_index_basic(index);
51
+ return judy_set_set(p_set , index);
52
+ }
53
+
54
+ VALUE ruby_JudySet_get(VALUE self , VALUE index) {
55
+ JudySet *p_set;
56
+ if( index == Qnil ) return Qnil ;
57
+ p_set = Get_Set(self) ;
58
+ check_index_basic(index);
59
+ return judy_set_has(p_set , index) ? Qtrue : Qfalse ;
60
+ }
61
+
62
+ VALUE ruby_JudySet_length(VALUE self) {
63
+ JudySet *p_set = Get_Set(self) ;
64
+ return judy_set_length(p_set);
65
+ }
66
+
67
+ VALUE ruby_JudySet_by_count(VALUE self, VALUE num) {
68
+ JudySet *p_set = Get_Set(self) ;
69
+ check_index_basic(num);
70
+ return judy_set_at_count(p_set, num ) ;
71
+ }
72
+
73
+ VALUE ruby_JudySet_mem_used(VALUE self) {
74
+ JudySet *p_set = Get_Set(self) ;
75
+ return judy_set_mem(p_set);
76
+ }
77
+
78
+ VALUE ruby_JudySet_first_index(VALUE self) {
79
+ JudySet *p_set = Get_Set(self) ;
80
+ return judy_set_first_index(p_set);
81
+ }
82
+
83
+ VALUE ruby_JudySet_next_index(VALUE self, VALUE index) {
84
+ JudySet *p_set = Get_Set(self) ;
85
+ check_index_basic(index);
86
+ return judy_set_next_index(p_set, index);
87
+ }
88
+
89
+ VALUE ruby_JudySet_last_index(VALUE self) {
90
+ JudySet *p_set = Get_Set(self) ;
91
+ return judy_set_last_index(p_set);
92
+ }
93
+
94
+ VALUE ruby_JudySet_clear(VALUE self) {
95
+ JudySet *p_set = Get_Set(self) ;
96
+ VALUE len = ruby_JudySet_length(self) ;
97
+ judy_set_clear(p_set);
98
+ return len;
99
+ }
100
+
101
+ VALUE ruby_JudySet_each(VALUE self) {
102
+ JudySet *p_set = Get_Set(self) ;
103
+ VALUE index = judy_set_first_index(p_set);
104
+ while(index != Qfalse ){
105
+ rb_yield(index);
106
+ index = judy_set_next_index(p_set, index);
107
+ }
108
+ return self;
109
+ }
110
+
111
+ VALUE ruby_JudySet_sum(VALUE self ) {
112
+ long int ret = 0;
113
+ JudySet *p_set = Get_Set(self) ;
114
+ VALUE index = judy_set_first_index(p_set);
115
+ while(index != Qfalse ){
116
+ ret += NUM2LONG(index) ;
117
+ index = judy_set_next_index(p_set, index);
118
+ }
119
+ return LONG2NUM(ret);
120
+ }
121
+
122
+ void Init_JudySet(void) {
123
+ VALUE cJudySet_klass = rb_define_class("JudySet", rb_cObject);
124
+ rb_include_module(cJudySet_klass, rb_eval_string("Enumerable"));
125
+ rb_define_singleton_method(cJudySet_klass, "new", ruby_JudySet_allocate, 0);
126
+ rb_define_method(cJudySet_klass, "do_set", ruby_JudySet_set, 2);
127
+ rb_define_method(cJudySet_klass, "set", ruby_JudySet_set, 2);
128
+ rb_define_method(cJudySet_klass, "[]=", ruby_JudySet_set, 2);
129
+ rb_define_method(cJudySet_klass, "add", ruby_JudySet_add, 1);
130
+ rb_define_method(cJudySet_klass, "delete", ruby_JudySet_delete, 1);
131
+ rb_define_method(cJudySet_klass, "unset", ruby_JudySet_delete, 1);
132
+ rb_define_method(cJudySet_klass, "get", ruby_JudySet_get, 1);
133
+ rb_define_method(cJudySet_klass, "do_get", ruby_JudySet_get, 1);
134
+ rb_define_method(cJudySet_klass, "[]", ruby_JudySet_get, 1);
135
+ rb_define_method(cJudySet_klass, "length", ruby_JudySet_length, 0);
136
+ rb_define_method(cJudySet_klass, "by_count", ruby_JudySet_by_count, 1);
137
+ rb_define_method(cJudySet_klass, "mem_used", ruby_JudySet_mem_used, 0);
138
+ rb_define_method(cJudySet_klass, "first_index", ruby_JudySet_first_index, 0);
139
+ rb_define_method(cJudySet_klass, "next_index", ruby_JudySet_next_index, 1);
140
+ rb_define_method(cJudySet_klass, "last_index", ruby_JudySet_last_index, 0);
141
+ rb_define_method(cJudySet_klass, "clear", ruby_JudySet_clear, 0);
142
+ rb_define_method(cJudySet_klass, "each", ruby_JudySet_each, 0);
143
+ rb_define_method(cJudySet_klass, "each_index", ruby_JudySet_each, 0);
144
+ rb_define_method(cJudySet_klass, "sum", ruby_JudySet_sum, 2);
145
+ }
146
+