bitmapper 0.0.1

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.
@@ -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: []