bitmapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,143 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+
5
+ #include "bit_bucket.h"
6
+
7
+ void _bit_bucket_set_bit_to(BitBucket* ptr,unsigned long long int byte_part, int bit_part, unsigned val){
8
+ val = (val == 0) ? 0 : 1;
9
+ switch(bit_part){
10
+ case 0: ptr->bucket[byte_part].f0 = val;break;
11
+ case 1: ptr->bucket[byte_part].f1 = val;break;
12
+ case 2: ptr->bucket[byte_part].f2 = val;break;
13
+ case 3: ptr->bucket[byte_part].f3 = val;break;
14
+ case 4: ptr->bucket[byte_part].f4 = val;break;
15
+ case 5: ptr->bucket[byte_part].f5 = val;break;
16
+ case 6: ptr->bucket[byte_part].f6 = val;break;
17
+ case 7: ptr->bucket[byte_part].f7 = val;break;
18
+ };
19
+ }
20
+
21
+ /*
22
+ sets the of given bit location to 1
23
+ @param BitBucket* pointer to the bit bucket to use, users
24
+ responsablity to ensure pointer is valid
25
+ @param num the bit location
26
+ */
27
+ int bit_bucket_set_bit(BitBucket* ptr,unsigned long long int num){
28
+ unsigned long long int byte_part=num/8, bit_part=num%8;
29
+ if(num > ptr->size) return 1;
30
+ _bit_bucket_set_bit_to(ptr, byte_part, bit_part, 1);
31
+ return 0;
32
+ }
33
+
34
+ /*
35
+ clears the state of given bit location to 0
36
+ @param BitBucket* pointer to the bit bucket to use, users
37
+ responsablity to ensure pointer is valid
38
+ @param num the bit location
39
+ */
40
+ int bit_bucket_clear_bit(BitBucket* ptr,unsigned long long int num){
41
+ unsigned long long int byte_part=num/8, bit_part=num%8;
42
+ if(num > ptr->size) return 1;
43
+ _bit_bucket_set_bit_to(ptr, byte_part, bit_part, 0);
44
+ return 0;
45
+ }
46
+
47
+ /*
48
+ returns the current state of given bit location
49
+ @param BitBucket* pointer to the bit bucket to use, users
50
+ responsablity to ensure pointer is valid
51
+ @param num the bit location
52
+ */
53
+ int bit_bucket_get_bit(BitBucket* ptr,unsigned long long int num){
54
+ unsigned long long int byte_part=num/8, bit_part=num%8;
55
+ if(num > ptr->size) return 2;
56
+ switch(bit_part){
57
+ case 0: return ptr->bucket[byte_part].f0;
58
+ case 1: return ptr->bucket[byte_part].f1;
59
+ case 2: return ptr->bucket[byte_part].f2;
60
+ case 3: return ptr->bucket[byte_part].f3;
61
+ case 4: return ptr->bucket[byte_part].f4;
62
+ case 5: return ptr->bucket[byte_part].f5;
63
+ case 6: return ptr->bucket[byte_part].f6;
64
+ case 7: return ptr->bucket[byte_part].f7;
65
+ };
66
+ }
67
+
68
+ /*
69
+ Resets the given BitBucket*
70
+ @param BitBucket* pointer to the bit bucket to use, users
71
+ responsablity to ensure pointer is valid
72
+ */
73
+ void bit_bucket_reset(BitBucket *ptr){
74
+ unsigned long long int count = ptr->size/8+1, i;
75
+ for(i=0;i<count;i++){
76
+ ptr->bucket[i] = (ByteBits){0,0,0,0,0,0,0,0};
77
+ }
78
+ }
79
+
80
+ /*
81
+ Creates BitBucket with the given size and allocates the requried
82
+ memory. A reset on all bits is done after creating the memory.
83
+ @param long long size Number of bits you want to allocate.
84
+ */
85
+ BitBucket* bit_bucket_create(unsigned long long int size){
86
+ unsigned long long int count = size/8 + 1;
87
+ BitBucket *ptr = (BitBucket*)malloc(sizeof(BitBucket));
88
+ ptr->size = size;
89
+ ptr->bucket = (ByteBits*)malloc(count*sizeof(ByteBits));
90
+ bit_bucket_reset(ptr);
91
+ return ptr;
92
+ }
93
+
94
+ /*
95
+ gives the size of the BitBucket in bytes
96
+ @param BitBucket* pointer to the bit bucket to use, users
97
+ responsablity to ensure pointer is valid
98
+ */
99
+ unsigned long long int bit_bucket_size(BitBucket *ptr){
100
+ return ptr->size/8+1;
101
+ }
102
+
103
+ /*
104
+ gives the string representation of BitBucket
105
+ @param BitBucket* pointer to the bit bucket to use, users
106
+ responsablity to ensure pointer is valid
107
+ */
108
+ void bit_bucket_string(BitBucket *ptr, unsigned char* raw){
109
+ unsigned long long int count = ptr->size/8+1, i;
110
+ if(ptr == NULL){
111
+ puts("######### ERROR: ptr is returning null");
112
+ }
113
+ memcpy(raw,ptr->bucket, count);
114
+ }
115
+
116
+ /*
117
+ Copies 1 Byte of given string to BitBucket* memory at given position
118
+ @param BitBucket* pointer to the bit bucket to use, users
119
+ responsablity to ensure pointer is valid
120
+ @param char* pointer to location where the 1 Byte is located
121
+ @pos unsigned long long int the offset byte location in BitBucket to be modified
122
+ */
123
+ int bit_bucket_load_byte(BitBucket* ptr,char *buf, unsigned long long int pos){
124
+ unsigned long long int count = ptr->size/8+1, i;
125
+ if(ptr == NULL){
126
+ printf("####### ERROR: ptr is returning null");
127
+ return 2;
128
+ }
129
+ if(count < pos) return 2;
130
+ memcpy(ptr->bucket+pos, buf, 1);
131
+ return 1;
132
+ }
133
+
134
+ /*
135
+ Frees all the memory allocated by bit_bucket_create
136
+ Should be called before dereferencing BitBucket pointer
137
+ returned by bit_bucket_create
138
+ @param BitBucket* the pointer to be cleared
139
+ */
140
+ void bit_bucket_free(BitBucket *ptr){
141
+ free(ptr->bucket);
142
+ free(ptr);
143
+ }
@@ -0,0 +1,37 @@
1
+ #ifndef BIT_BUCKET
2
+ #define BIT_BUCKET
3
+
4
+ /*
5
+ this is the bitfield which takes 1 byte(8-bits) of space in memory
6
+ */
7
+ typedef struct ByteBits{
8
+ unsigned char f0:1;
9
+ unsigned char f1:1;
10
+ unsigned char f2:1;
11
+ unsigned char f3:1;
12
+ unsigned char f4:1;
13
+ unsigned char f5:1;
14
+ unsigned char f6:1;
15
+ unsigned char f7:1;
16
+ } ByteBits;
17
+
18
+ /*
19
+ wrapper for sequence of ByteBits number of Bytebits will be
20
+ given_size(in bits)/8 + 1
21
+ */
22
+ typedef struct BitBucket{
23
+ ByteBits *bucket;
24
+ unsigned long long int size; /* size in bits as given */
25
+ } BitBucket;
26
+
27
+ void _bit_bucket_set_bit_to(BitBucket* ptr,unsigned long long int byte_part, int bit_part, unsigned val);
28
+ int bit_bucket_set_bit(BitBucket* ptr,unsigned long long int num);
29
+ int bit_bucket_clear_bit(BitBucket* ptr,unsigned long long int num);
30
+ int bit_bucket_get_bit(BitBucket* ptr,unsigned long long int num);
31
+ void bit_bucket_reset(BitBucket *ptr);
32
+ BitBucket* bit_bucket_create(unsigned long long int size);
33
+ unsigned long long int bit_bucket_size(BitBucket *ptr);
34
+ void bit_bucket_string(BitBucket *ptr, unsigned char* raw);
35
+ int bit_bucket_load_byte(BitBucket* ptr,char *buf, unsigned long long int pos);
36
+ void bit_bucket_free(BitBucket *ptr);
37
+ #endif /* BIT_BUCKET */
@@ -0,0 +1,349 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <math.h>
5
+
6
+ #include "bit_mapper_wrap.h"
7
+ /* #include "bit_bucket.c" */
8
+
9
+ /*
10
+ Creates empty Bitmapper*. Without BitBucket pointers.
11
+ */
12
+ Bitmapper* create_map(){
13
+ Bitmapper* map;
14
+ map = (Bitmapper*)malloc(sizeof(Bitmapper));
15
+ return map;
16
+ }
17
+
18
+ /*
19
+ Buckets are not allocated space a this point. They will be created
20
+ on the fly.
21
+ @param int Number of digits from left(Most Significant Digits) to be used
22
+ for indexing 10^(10-index) will be the size of the bucket in bits.
23
+ */
24
+ void allocate_map(Bitmapper* map, int index_len){
25
+ unsigned long long int size = pow(10, index_len),i;
26
+ map->bkts = (BitBucket**)malloc(size*sizeof(BitBucket*));
27
+ for(i=0;i<size; i++){
28
+ map->bkts[i] = NULL;
29
+ }
30
+ map->bkt_size = pow(10, 10 - index_len);
31
+ map->bkt_count = size;
32
+ map->index_len = index_len;
33
+ sprintf(map->fill_str, "%%llu%%0%illu\n",10-index_len);
34
+ }
35
+
36
+ /*
37
+ Clears the memory allocated by create_map and create_bucket_for(if available)
38
+ @param Bitmapper* the Bitmapper* object to clear, only the buckets in
39
+ the bitmap obj and the buckets pointer will be freed
40
+ */
41
+ void free_map(Bitmapper* map){
42
+ unsigned long long int i;
43
+ for(i=0;i<map->bkt_count; i++){
44
+ if((map->bkts[i])!=NULL) bit_bucket_free(map->bkts[i]);
45
+ }
46
+ free(map->bkts);
47
+ free(map);
48
+ }
49
+
50
+ /*
51
+ Creates a Bitbucket with the given size and returns the pointer
52
+ @param BitBucket* the pointer to the bucket
53
+ @param unsigned long long int the size of bucket in bits
54
+ */
55
+ BitBucket* create_bucket_for(BitBucket* bkt, unsigned long long int size){
56
+ bkt = bit_bucket_create(size);
57
+ return bkt;
58
+ }
59
+
60
+ /*
61
+ Adds the given number to the bucket reperesented by the given index
62
+ @param Bitmapper* the mapepr object to use
63
+ @param unsigned long long int the offset to be added(if the offset is greater
64
+ than bucket size it is rejected)
65
+ @param unsigned long long int the index of the bucket that will hold the number
66
+ */
67
+ int add_num_in_bkt(Bitmapper* map,unsigned long long int offset, unsigned long long int bkt_index){
68
+ if(bkt_index > map->bkt_count) return 1;
69
+ if((map->bkts[bkt_index]) == NULL)
70
+ map->bkts[bkt_index] = (BitBucket*)create_bucket_for(map->bkts[bkt_index], map->bkt_size);
71
+ if(bit_bucket_set_bit(map->bkts[bkt_index], offset) != 0){
72
+ puts("out of range");
73
+ return 1;/* ERROR out of range */
74
+ }
75
+ return 0;
76
+ }
77
+
78
+ /*
79
+ Wrapper for add_num_in_bkt, splits the given number into index and
80
+ bit location
81
+ @param Bitmapper* the mapepr object to use
82
+ @param unsigned long long int the number
83
+ */
84
+ int add_num(Bitmapper* map,unsigned long long int full_num){
85
+ unsigned long long int offset, bkt_index, div;
86
+ div = pow(10, 10-map->index_len);
87
+ bkt_index = full_num / div;
88
+ offset = full_num % div;
89
+ return add_num_in_bkt(map, offset, bkt_index);
90
+ }
91
+
92
+ /*
93
+ Removes the given number from the bucket reperesented by the given index
94
+ @param Bitmapper* the mapepr object to use
95
+ @param unsigned long long int the offset to be Removed(if the offset is greater
96
+ than bucket size it is rejected)
97
+ @param unsigned long long int the index of the bucket that would be hold the number
98
+ */
99
+ int remove_num_in_bkt(Bitmapper* map,unsigned long long int offset, unsigned long long int bkt_index){
100
+ if(bkt_index > map->bkt_count) return 1;
101
+ if(map->bkts[bkt_index] == NULL)
102
+ return 0;
103
+ if(bit_bucket_clear_bit(map->bkts[bkt_index], offset) != 0){
104
+ puts("out of range");
105
+ return 1;/* ERROR out of range */
106
+ }
107
+ return 0;
108
+ }
109
+
110
+ /*
111
+ Wrapper for remove_num_in_bkt, splits the given number into index and
112
+ bit location
113
+ @param Bitmapper* the mapepr object to use
114
+ @param unsigned long long int the number
115
+ */
116
+ int remove_num(Bitmapper* map,unsigned long long int full_num){
117
+ unsigned long long int offset, bkt_index, div;
118
+ div = pow(10, 10-map->index_len);
119
+ bkt_index = full_num / div;
120
+ offset = full_num % div;
121
+ return remove_num_in_bkt(map, offset, bkt_index);
122
+ }
123
+
124
+ /*
125
+ returns the status of the given bit offset in the bucket reperesented by the given index
126
+ @param Bitmapper* the mapepr object to use
127
+ @param unsigned long long int the offset to be checked(if the number is greater
128
+ than bucket size it is rejected)
129
+ @param unsigned long long int the index of the bucket that would be hold the number
130
+ */
131
+ int status_num_in_bkt(Bitmapper* map,unsigned long long int offset, unsigned long long int bkt_index){
132
+ if(bkt_index > map->bkt_count) return 2;
133
+ if(map->bkts[bkt_index] == NULL)
134
+ return 0;
135
+ return bit_bucket_get_bit(map->bkts[bkt_index], offset);
136
+ }
137
+
138
+ /*
139
+ Wrapper for status_num_in_bkt, splits the given number into index and
140
+ bit location
141
+ @param Bitmapper* the mapepr object to use
142
+ @param unsigned long long int the number
143
+ */
144
+ int status_num(Bitmapper* map,unsigned long long int full_num){
145
+ unsigned long long int offset, bkt_index, div;
146
+ div = pow(10, 10-map->index_len);
147
+ bkt_index = full_num / div;
148
+ offset = full_num % div;
149
+ return status_num_in_bkt(map, offset, bkt_index);
150
+ }
151
+
152
+ /*
153
+ A wrapper method which take a file and loads all the numbers in that
154
+ file into Bitmapper*. Works with DOS & unix files.
155
+ @param Bitmapper* the mapepr object to use
156
+ @param FILE* the file pointer to the opened file
157
+
158
+ TODO: check for validity of number
159
+ */
160
+ int add_numbers_in_file(Bitmapper* map,FILE *in){
161
+ char scan_str[20];
162
+ char msisdn[15], index[map->index_len], rest_num[10-map->index_len];
163
+ sprintf(scan_str, "%%%is%%%is\n",map->index_len, 10-map->index_len);
164
+ while(fgets(msisdn, 15, in)!=NULL){
165
+ sscanf(msisdn,scan_str, index, rest_num);
166
+ add_num_in_bkt(map, atoll(rest_num), atoll(index) );
167
+ }
168
+ }
169
+
170
+ /*
171
+ A wrapper method which take a file and removes all the numbers in that
172
+ file from Bitmapper* if the number exist. Works with DOS & unix files.
173
+ @param Bitmapper* the mapepr object to use
174
+ @param FILE* the file pointer to the opened file
175
+
176
+ TODO: check for validity of number
177
+ */
178
+ int remove_numbers_in_file(Bitmapper* map,FILE *del){
179
+ char scan_str[20];
180
+ char msisdn[15], index[map->index_len], rest_num[10-map->index_len];
181
+ sprintf(scan_str, "%%%is%%%is\n",map->index_len, 10-map->index_len);
182
+ while(fgets(msisdn, 15, del)!=NULL){
183
+ sscanf(msisdn,scan_str, index, rest_num);
184
+ remove_num_in_bkt(map, atoll(rest_num), atoll(index) );
185
+ }
186
+ }
187
+
188
+ /*
189
+ Dumps the number in bucket(if available) into the given file
190
+ @param Bitmapper* the mapepr object to use
191
+ @param FILE* the file pointer to the opened file
192
+ @param unsigned long long int index to the bucket to consider
193
+ */
194
+ int dump_bucket_to_file(Bitmapper* map, FILE* fp, unsigned long long int bkt_index){
195
+ unsigned long long int i;
196
+ unsigned num;
197
+ if(map->bkt_count<=bkt_index) return 1;
198
+
199
+ if(map->bkts[bkt_index] == NULL)
200
+ return 2;
201
+ for(i=0;i<map->bkt_size;i++){
202
+ num = bit_bucket_get_bit(map->bkts[bkt_index], i);
203
+ if(num==1){
204
+ fprintf(fp, map->fill_str, bkt_index, i);
205
+ }
206
+ }
207
+ return 0;
208
+ }
209
+
210
+ /*
211
+ Dumps all numbers set in Bitmapper* in into the given file
212
+ @param Bitmapper* the mapepr object to use
213
+ @param FILE* the file pointer to the opened file
214
+ @param unsigned long long int the length of index
215
+ */
216
+ int dump_all_to_file(Bitmapper* map, FILE* fp){
217
+ unsigned long long int i;
218
+ for(i=0;i<map->bkt_count;i++){
219
+ dump_bucket_to_file(map, fp, i);
220
+ }
221
+ return 0;
222
+ }
223
+
224
+ /*
225
+ Dumps the bucket's(if available) bit values into the given file
226
+ @param Bitmapper* the mapepr object to use
227
+ @param FILE* the file pointer to the opened file
228
+ @param unsigned long long int index to the bucket to consider
229
+
230
+ TODO: If the bucket doesn't exist, dump empty string equal to the
231
+ size of the bucket
232
+ */
233
+ int dump_bucket_str_to_file(Bitmapper* map, FILE* fp,unsigned long long int bkt_index){
234
+ unsigned char* raw = (unsigned char*)malloc(map->bkt_size/8+1);
235
+ BitBucket* tmp;
236
+ if(map->bkts[bkt_index] == NULL)
237
+ tmp = bit_bucket_create(map->bkt_size);
238
+ else
239
+ tmp = map->bkts[bkt_index];
240
+ bit_bucket_string(tmp, raw);
241
+ fwrite(raw, 1, bit_bucket_size(tmp), fp);
242
+
243
+ if(map->bkts[bkt_index] == NULL)
244
+ bit_bucket_free(tmp);
245
+ free(raw);
246
+ return 0;
247
+ }
248
+
249
+ /*
250
+ Dumps all bucket's bit values into the given file
251
+ @param Bitmapper* the mapepr object to use
252
+ @param FILE* the file pointer to the opened file
253
+ @param unsigned long long int the length of index
254
+ */
255
+ int dump_all_str_to_file(Bitmapper* map, FILE* fp){
256
+ unsigned long long int i;
257
+ for(i=0;i<map->bkt_count;i++){
258
+ dump_bucket_str_to_file(map, fp, i);
259
+ }
260
+ return 0;
261
+ }
262
+
263
+ /*
264
+ Loads binary string from file to given bitmap bucket. Creates
265
+ bucket if it doesn't exist
266
+ @param Bitmapper* the mapepr object to use
267
+ @param FILE* the file pointer to the opened file
268
+ @param unsigned long long int the index of bucket to load
269
+ */
270
+ int load_str_file_to_bucket(Bitmapper* map, FILE* fp,unsigned long long int bkt_index){
271
+ unsigned long long int size,i;
272
+ char buf[1];
273
+ if(map->bkts[bkt_index] == NULL){
274
+ puts("creating bucket");
275
+ map->bkts[bkt_index] = (BitBucket*)create_bucket_for(map->bkts[bkt_index], map->bkt_size);
276
+ }
277
+
278
+ size = bit_bucket_size(map->bkts[bkt_index]);
279
+ for(i=0;i<size;i++){
280
+ fread(buf, 1, 1, fp);
281
+ if(buf == NULL) break;
282
+ bit_bucket_load_byte(map->bkts[bkt_index], buf, i);
283
+ }
284
+ return 0;
285
+ }
286
+
287
+ /*
288
+ Loads binary string from file to given bitmap-> Creates
289
+ bucket if it doesn't exist.
290
+ * The load is one-one bit maping.
291
+ * bits exceding Bitmapper* size(buckets count * size of each bucket
292
+ in bits) will be ignored
293
+ * the size of the bucket reperesented in file string must be equal
294
+ to the size of bucket in Bitmapper*.
295
+ @param Bitmapper* the mapepr object to use
296
+ @param FILE* the file pointer to the opened file
297
+ @param unsigned long long int the index of bucket to load
298
+ */
299
+ int load_str_file(Bitmapper* map, FILE* fp){
300
+ unsigned long long int size, i, bkt_no;
301
+ char buf[1];
302
+ for(bkt_no = 0;bkt_no < map->bkt_count; bkt_no++){
303
+ if(map->bkts[bkt_no] == NULL){
304
+ // TODO
305
+ puts("creating bucket");
306
+ map->bkts[bkt_no] = (BitBucket*)create_bucket_for(map->bkts[bkt_no], map->bkt_size);
307
+ }
308
+ size = bit_bucket_size(map->bkts[bkt_no]);
309
+ for(i=0;i<size;i++){
310
+ fread(buf, 1, 1, fp);
311
+ if(buf == NULL) return 0;
312
+ bit_bucket_load_byte(map->bkts[bkt_no], buf, i);
313
+ }
314
+ return 0;
315
+ }
316
+ }
317
+
318
+ void test(){
319
+ int index_len = 6;
320
+ FILE *in, *out, *del, *str_out, *str_in;
321
+ Bitmapper* map = create_map();
322
+ allocate_map(map, index_len);
323
+ in = fopen("/tmp/ncpr/out.txt","r");
324
+ add_numbers_in_file(map, in);
325
+ /* in = fopen("test/data/1-add.txt","r"); */
326
+ /* del = fopen("test/data/1-del.txt","r"); */
327
+ out = fopen("/tmp/ncpr/out2.txt","w");
328
+ /* str_out = fopen("/tmp/ncpr/str_out.txt","w"); */
329
+ /* add_numbers_in_file(map, in, index_len); */
330
+ /* // remove_numbers_in_file(map, del); */
331
+ /* /\* dump_all_str_to_file( map, str_out); *\/ */
332
+ /* dump_bucket_str_to_file(map, str_out, 934793); */
333
+ /* fclose(str_out); */
334
+ /* str_in = fopen("/tmp/ncpr/str_out.txt","r"); */
335
+ /* load_str_file_to_bucket(map, str_in, 934793); */
336
+ /* puts("dumping to file"); */
337
+ dump_all_to_file(map, out);
338
+
339
+
340
+ fclose(in);
341
+ /* fclose(del); */
342
+ fclose(out);
343
+ /* fclose(str_in); */
344
+ free_map(map);
345
+ }
346
+
347
+ void main(){
348
+ test();
349
+ }
@@ -0,0 +1,39 @@
1
+ #include "bit_bucket.h"
2
+
3
+ #ifndef BIT_MAPPER_WRAP
4
+ #define BIT_MAPPER_WRAP
5
+
6
+ /*
7
+ Bitmapper Object holds the buckets pointer and other info
8
+ */
9
+ typedef struct Bitmapper{
10
+ BitBucket** bkts; /* pointer to list of pointers(count=bkt_count) */
11
+ unsigned long long int bkt_count; /* number of buckets in Bitmapper */
12
+ unsigned long long int bkt_size; /* size of each bucket in bits */
13
+ /* the format specifier used to dump number to file from buckets */
14
+ int index_len;
15
+ char fill_str[20];
16
+ } Bitmapper;
17
+
18
+ Bitmapper* create_map();
19
+ void allocate_map(Bitmapper*, int);
20
+ void free_map(Bitmapper*);
21
+ BitBucket* create_bucket_for(BitBucket*, unsigned long long int);
22
+ int add_num_in_bkt(Bitmapper* ,unsigned long long int, unsigned long long int);
23
+ int add_num(Bitmapper* ,unsigned long long int);
24
+ int remove_num_in_bkt(Bitmapper* ,unsigned long long int, unsigned long long int);
25
+ int remove_num(Bitmapper* ,unsigned long long int);
26
+ int status_num_in_bkt(Bitmapper* ,unsigned long long int, unsigned long long int);
27
+ int status_num(Bitmapper* ,unsigned long long int);
28
+
29
+ int add_numbers_in_file(Bitmapper* ,FILE*);
30
+ int remove_numbers_in_file(Bitmapper* ,FILE* );
31
+ int dump_bucket_to_file(Bitmapper*, FILE* , unsigned long long int);
32
+ int dump_all_to_file(Bitmapper* , FILE* );
33
+
34
+ int dump_bucket_str_to_file(Bitmapper* , FILE* ,unsigned long long int );
35
+ int dump_all_str_to_file(Bitmapper* , FILE*);
36
+ int load_str_file_to_bucket(Bitmapper* , FILE* ,unsigned long long int);
37
+ int load_str_file(Bitmapper* , FILE*);
38
+
39
+ #endif /* BIT_MAPPER_WRAP */
@@ -0,0 +1,198 @@
1
+ #include "ruby.h"
2
+ #include "bit_mapper_wrap.h"
3
+
4
+ static VALUE rb_cBitmapper;
5
+ static ID index_len;
6
+
7
+ VALUE bm_init(VALUE self, VALUE len){
8
+ Bitmapper* map;
9
+ Data_Get_Struct(self, Bitmapper, map);
10
+ allocate_map(map, FIX2INT(len));
11
+ rb_iv_set(self, "@index_len", len);
12
+ return self;
13
+ }
14
+
15
+ /*
16
+ TODO: check if void* to Bitmapper* is a safe cast
17
+ */
18
+ void bm_free(void *p){
19
+ free_map((Bitmapper*)p);
20
+ }
21
+
22
+ VALUE bm_alloc(VALUE self){
23
+ Bitmapper* map;
24
+ map = create_map();
25
+ return Data_Wrap_Struct(self, 0, bm_free, map);
26
+ }
27
+
28
+ /*
29
+ Generates current index and assign it to @indexes variable
30
+ */
31
+ VALUE bm_referesh_indexes(VALUE self){
32
+ Bitmapper* map;
33
+ ID id_push;
34
+ VALUE arr;
35
+ FILE *fp;
36
+ unsigned long long int i;
37
+ arr = rb_ary_new();
38
+ id_push = rb_intern("push");
39
+ Data_Get_Struct(self, Bitmapper, map);
40
+
41
+ rb_funcall(arr, rb_intern("clear"), 0);
42
+ for(i=0;i<map->bkt_count;i++)
43
+ if(map->bkts[i] != NULL)
44
+ rb_funcall(arr, id_push, 1, LL2NUM(i));
45
+
46
+ rb_iv_set(self, "@indexes", arr);
47
+ return self;
48
+ }
49
+
50
+ /*
51
+ Call to refresh indexs in @indexes
52
+ and return the value
53
+ */
54
+ VALUE bm_get_indexes(VALUE self){
55
+ bm_referesh_indexes(self);
56
+ return rb_iv_get(self, "@indexes");
57
+ }
58
+
59
+ VALUE bm_add_from_file(VALUE self, VALUE file_str){
60
+ Bitmapper* map;
61
+ FILE *fp;
62
+ Data_Get_Struct(self, Bitmapper, map);
63
+ fp = fopen(RSTRING_PTR(StringValue(file_str)), "r");
64
+ if(fp == NULL) rb_raise(rb_eIOError, "file counld not be opened");
65
+ add_numbers_in_file(map, fp);
66
+ fclose(fp);
67
+ return self;
68
+ }
69
+
70
+ VALUE bm_remove_from_file(VALUE self, VALUE file_str){
71
+ Bitmapper* map;
72
+ FILE *fp;
73
+ Data_Get_Struct(self, Bitmapper, map);
74
+ fp = fopen(RSTRING_PTR(StringValue(file_str)), "r");
75
+ if(fp == NULL) rb_raise(rb_eIOError, "file counld not be opened");
76
+ remove_numbers_in_file(map, fp);
77
+ fclose(fp);
78
+ return self;
79
+ }
80
+
81
+ VALUE bm_dump_to_file(VALUE self, VALUE file_str){
82
+ Bitmapper* map;
83
+ FILE *fp;
84
+ Data_Get_Struct(self, Bitmapper, map);
85
+ fp = fopen(RSTRING_PTR(StringValue(file_str)), "w");
86
+ if(fp == NULL) rb_raise(rb_eIOError, "file counld not be opened");
87
+ dump_all_to_file(map, fp);
88
+ fclose(fp);
89
+ return self;
90
+ }
91
+
92
+ VALUE bm_load_str_to_bkt(VALUE self, VALUE file_str, VALUE index){
93
+ Bitmapper* map;
94
+ FILE *fp;
95
+ Data_Get_Struct(self, Bitmapper, map);
96
+ fp = fopen(RSTRING_PTR(StringValue(file_str)), "r");
97
+ if(fp == NULL) rb_raise(rb_eIOError, "file counld not be opened");
98
+ load_str_file_to_bucket(map, fp, NUM2LL(index));
99
+ fclose(fp);
100
+ return self;
101
+ }
102
+
103
+ VALUE bm_dump_bkt_str(VALUE self, VALUE file_str, VALUE index){
104
+ Bitmapper* map;
105
+ FILE *fp;
106
+ Data_Get_Struct(self, Bitmapper, map);
107
+ fp = fopen(RSTRING_PTR(StringValue(file_str)), "w");
108
+ if(fp == NULL) rb_raise(rb_eIOError, "file counld not be opened");
109
+ dump_bucket_str_to_file(map, fp, NUM2LL(index));
110
+ fclose(fp);
111
+ return self;
112
+ }
113
+
114
+ /*
115
+ helper method, works as to_i for various datatypes
116
+ */
117
+ unsigned long long int bm_to_ll(VALUE num){
118
+ VALUE tmp;
119
+ switch(TYPE(num)){
120
+ case T_STRING:
121
+ tmp = rb_funcall(num, rb_intern("to_i"), 0); /* hack */
122
+ return NUM2LL(tmp);
123
+ case T_FIXNUM:
124
+ case T_BIGNUM:
125
+ return NUM2LL(num);
126
+ }
127
+ return 0;
128
+ }
129
+
130
+ /*
131
+ adds the given number to bitmapper
132
+ */
133
+ VALUE bm_set(VALUE self, VALUE num){
134
+ int status;
135
+ Bitmapper* map;
136
+
137
+ Data_Get_Struct(self, Bitmapper, map);
138
+ status = add_num(map, bm_to_ll(num));
139
+ if(status==0)
140
+ return (VALUE)Qtrue;
141
+ else
142
+ rb_raise(rb_eTypeError, "not valid number");
143
+ return (VALUE)Qfalse;
144
+ }
145
+
146
+ /*
147
+ removes the given number from bitmapper
148
+ */
149
+ VALUE bm_clear(VALUE self, VALUE num){
150
+ int status;
151
+ Bitmapper* map;
152
+
153
+ Data_Get_Struct(self, Bitmapper, map);
154
+ status = remove_num(map, bm_to_ll(num));
155
+ if(status==0)
156
+ return (VALUE)Qtrue;
157
+ else
158
+ rb_raise(rb_eTypeError, "not valid number");
159
+ return (VALUE)Qfalse;
160
+ }
161
+
162
+ /*
163
+ returns true if the provided number is present in bitmap or returns
164
+ false
165
+ */
166
+ VALUE bm_num_status(VALUE self, VALUE num){
167
+ int status;
168
+ VALUE return_val;
169
+ Bitmapper* map;
170
+
171
+ Data_Get_Struct(self, Bitmapper, map);
172
+ status = status_num(map, bm_to_ll(num));
173
+ if(status==1)
174
+ return (VALUE)Qtrue;
175
+ else if(status == 0)
176
+ return (VALUE)Qfalse;
177
+ else
178
+ rb_raise(rb_eTypeError, "not valid number");
179
+ return (VALUE)Qfalse;
180
+
181
+ }
182
+
183
+ void Init_bitmapper(){
184
+ rb_cBitmapper = rb_define_class("Bitmapper", rb_cObject);
185
+ rb_define_alloc_func(rb_cBitmapper, bm_alloc);
186
+ rb_define_method(rb_cBitmapper, "initialize", bm_init, 1);
187
+ rb_define_method(rb_cBitmapper, "get_indexes", bm_get_indexes, 0);
188
+ rb_define_method(rb_cBitmapper, "add", bm_add_from_file, 1);
189
+ rb_define_method(rb_cBitmapper, "remove", bm_remove_from_file, 1);
190
+ rb_define_method(rb_cBitmapper, "dump_to", bm_dump_to_file, 1);
191
+ rb_define_method(rb_cBitmapper, "load_from_str", bm_load_str_to_bkt, 2);
192
+ rb_define_method(rb_cBitmapper, "dump_to_str", bm_dump_bkt_str, 2);
193
+
194
+ rb_define_method(rb_cBitmapper, "status?", bm_num_status, 1);
195
+ rb_define_method(rb_cBitmapper, "set", bm_set, 1);
196
+ rb_define_method(rb_cBitmapper, "clear", bm_clear, 1);
197
+
198
+ }
@@ -0,0 +1,11 @@
1
+ # Loads mkmf which is used to make makefiles for Ruby extensions
2
+ require 'mkmf'
3
+
4
+ # Give it a name
5
+ extension_name = 'bitmapper'
6
+
7
+ # The destination
8
+ dir_config("bitmapper/#{extension_name}")
9
+
10
+ # Do the work
11
+ create_makefile("bitmapper/#{extension_name}")
data/lib/bitmapper.rb ADDED
@@ -0,0 +1,5 @@
1
+ begin
2
+ require 'bitmapper/bitmapper'
3
+ rescue LoadError =>e
4
+ puts "Error loading c binding for bitmapepr"
5
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitmapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Goutham Vel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-11 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: PENDING
15
+ email: gouthamvel@gmail.com
16
+ executables: []
17
+ extensions:
18
+ - ext/bitmapper/extconf.rb
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/bitmapper.rb
22
+ - ext/bitmapper/bitmapper.c
23
+ - ext/bitmapper/bit_bucket.c
24
+ - ext/bitmapper/bit_mapper_wrap.c
25
+ - ext/bitmapper/bit_bucket.h
26
+ - ext/bitmapper/bit_mapper_wrap.h
27
+ - ext/bitmapper/extconf.rb
28
+ homepage: ''
29
+ licenses: []
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.23
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: A fast bit map filter!
52
+ test_files: []