summaryrefslogtreecommitdiff
path: root/src/ebitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ebitmap.c')
-rw-r--r--src/ebitmap.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/ebitmap.c b/src/ebitmap.c
index cc6a915..be6b591 100644
--- a/src/ebitmap.c
+++ b/src/ebitmap.c
@@ -71,6 +71,82 @@ int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1)
return 0;
}
+int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
+{
+ unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2));
+ ebitmap_init(dst);
+ for (i=0; i < length; i++) {
+ if (ebitmap_get_bit(e1, i) && ebitmap_get_bit(e2, i)) {
+ int rc = ebitmap_set_bit(dst, i, 1);
+ if (rc < 0)
+ return rc;
+ }
+ }
+ return 0;
+}
+
+int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
+{
+ unsigned int i, length = max(ebitmap_length(e1), ebitmap_length(e2));
+ ebitmap_init(dst);
+ for (i=0; i < length; i++) {
+ int val = ebitmap_get_bit(e1, i) ^ ebitmap_get_bit(e2, i);
+ int rc = ebitmap_set_bit(dst, i, val);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit)
+{
+ unsigned int i;
+ ebitmap_init(dst);
+ for (i=0; i < maxbit; i++) {
+ int val = ebitmap_get_bit(e1, i);
+ int rc = ebitmap_set_bit(dst, i, !val);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit)
+{
+ ebitmap_t e3;
+ ebitmap_init(dst);
+ int rc = ebitmap_not(&e3, e2, maxbit);
+ if (rc < 0)
+ return rc;
+ rc = ebitmap_and(dst, e1, &e3);
+ ebitmap_destroy(&e3);
+ if (rc < 0)
+ return rc;
+ return 0;
+}
+
+unsigned int ebitmap_cardinality(ebitmap_t *e1)
+{
+ unsigned int i, count = 0;
+ for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++)
+ if (ebitmap_get_bit(e1, i))
+ count++;
+ return count;
+}
+
+int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2)
+{
+ if (ebitmap_cmp(e1, e2))
+ return 0;
+ ebitmap_t tmp;
+ int rc = ebitmap_xor(&tmp, e1, e2);
+ if (rc < 0)
+ return -1;
+ int distance = ebitmap_cardinality(&tmp);
+ ebitmap_destroy(&tmp);
+ return distance;
+}
+
int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2)
{
ebitmap_node_t *n1, *n2;