Skip to content

Commit 4a734e4

Browse files
committed
Adding initial bit vector fiddle.
1 parent b5ba41c commit 4a734e4

File tree

4 files changed

+176
-0
lines changed

4 files changed

+176
-0
lines changed

bitvec/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
3+
## Use the variable PROJECT_NAME for changing the target name
4+
set( PROJECT_NAME "bitvec" )
5+
6+
## Set our project name
7+
project(${PROJECT_NAME})
8+
9+
## Use all the *.cpp files we found under this folder for the project
10+
FILE(GLOB SRCS "*.c" "*.h")
11+
12+
## Define the executable
13+
add_executable(${PROJECT_NAME} ${SRCS})

bitvec/bitvec.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
2+
#include <stdint.h>
3+
#include <string.h>
4+
#include <stdlib.h>
5+
#include "bitvec.h"
6+
7+
8+
struct bitvec {
9+
int size;
10+
uint64_t data[];
11+
};
12+
13+
bitvec_p bitvec_create(int size)
14+
{
15+
int actual_entries = (size + 63)/64;
16+
bitvec_p result = NULL;
17+
18+
if((result = calloc(1, sizeof(*result) + (actual_entries * sizeof(uint64_t)))) == NULL) {
19+
return NULL;
20+
}
21+
22+
result->size = size;
23+
24+
return result;
25+
}
26+
27+
28+
29+
void bitvec_destroy(bitvec_p bv)
30+
{
31+
if(bv) {
32+
free(bv);
33+
}
34+
}
35+
36+
37+
int bitvec_get(bitvec_p bv, int index)
38+
{
39+
uint64_t mask = 0;
40+
41+
if(!bv) {
42+
return -1;
43+
}
44+
45+
if(index <0 || index >= bv->size) {
46+
return -1;
47+
}
48+
49+
mask = ((uint64_t)1 << (index % 64));
50+
51+
return ((mask & bv->data[index/64]) ? 1 : 0);
52+
}
53+
54+
55+
56+
int bitvec_set(bitvec_p bv, int index, int val)
57+
{
58+
int result = 0;
59+
uint64_t mask = 0;
60+
61+
result = bitvec_get(bv, index);
62+
63+
if(result < 0) {
64+
return result;
65+
}
66+
67+
mask = ((uint64_t)1 << (index % 64));
68+
69+
if(val == 0) {
70+
bv->data[index/64] &= (~mask);
71+
} else {
72+
bv->data[index/64] |= mask;
73+
}
74+
75+
return result;
76+
}
77+
78+
79+
80+
void bitvec_clear(bitvec_p bv, int val)
81+
{
82+
int elem_count = 0;
83+
uint64_t clear_val = (val ? 0xFFFFFFFFFFFFFFFF : 0x0000000000000000);
84+
85+
if(!bv) {
86+
return;
87+
}
88+
89+
elem_count = bv->size / 64;
90+
91+
for(int i=0; i < elem_count; i++) {
92+
bv->data[i] = clear_val;
93+
}
94+
}
95+
96+
97+
98+
int bitvec_find_first(bitvec_p bv, int val)
99+
{
100+
int elem_count = 0;
101+
102+
if(!bv) {
103+
return -1;
104+
}
105+
106+
elem_count = bv->size / 64;
107+
108+
for(int i=0; i < elem_count; i++) {
109+
uint64_t elem = (val ? bv->data[i] : ~(bv->data[i]));
110+
int bit_index = ffsll(elem);
111+
112+
if(bit_index != 0) {
113+
return (i * 64) + (bit_index - 1); /* bit_index is 1-64, not 0-63. 0 means no bits set. */
114+
}
115+
}
116+
117+
return -1;
118+
}
119+

bitvec/bitvec.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
typedef struct bitvec *bitvec_p;
2+
3+
extern bitvec_p bitvec_create(int size);
4+
extern void bitvec_destroy(bitvec_p bv);
5+
extern int bitvec_get(bitvec_p bv, int index);
6+
extern int bitvec_set(bitvec_p bv, int index, int val);
7+
extern void bitvec_clear(bitvec_p, int val);
8+
extern int bitvec_find_first(bitvec_p bv, int val);

bitvec/main.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <assert.h>
2+
#include <stdio.h>
3+
#include "bitvec.h"
4+
5+
#define BITVEC_SIZE (101)
6+
7+
int main(int argc, const char **argv)
8+
{
9+
bitvec_p bv = bitvec_create(BITVEC_SIZE);
10+
int old_val = 0;
11+
int index = 0;
12+
13+
assert(bv != NULL);
14+
15+
/* test == basic bit setting */
16+
old_val = bitvec_set(bv, 40, 1);
17+
assert(old_val == 0);
18+
19+
/* get bit finding */
20+
index = bitvec_find_first(bv, 1);
21+
assert(index == 40);
22+
23+
old_val = bitvec_set(bv, 0, 1);
24+
assert(old_val == 0);
25+
26+
index = bitvec_find_first(bv, 1);
27+
assert(index == 0);
28+
29+
index = bitvec_find_first(bv, 0);
30+
assert(index == 1);
31+
32+
33+
bitvec_destroy(bv);
34+
35+
return 0;
36+
}

0 commit comments

Comments
 (0)