File: bitvector.c

package info (click to toggle)
ruby-ferret 0.11.8.4%2Bdebian-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,368 kB
  • sloc: ansic: 69,786; ruby: 8,131; makefile: 5
file content (96 lines) | stat: -rw-r--r-- 2,150 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "bitvector.h"
#include "internal.h"
#include <string.h>

BitVector *bv_new_capa(int capa)
{
    BitVector *bv = ALLOC_AND_ZERO(BitVector);

    /* The capacity passed by the user is number of bits allowed, however we
     * store capacity as the number of words (U32) allocated. */
    bv->capa = max2(TO_WORD(capa), 4);
    bv->bits = ALLOC_AND_ZERO_N(u32, bv->capa);
    bv->curr_bit = -1;
    bv->ref_cnt = 1;
    return bv;
}

BitVector *bv_new()
{
    return bv_new_capa(BV_INIT_CAPA);
}

void bv_destroy(BitVector *bv)
{
    if (--(bv->ref_cnt) == 0) {
        free(bv->bits);
        free(bv);
    }
}

void bv_clear(BitVector *bv)
{
    memset(bv->bits, 0, bv->capa * sizeof(u32));
    bv->extends_as_ones = 0;
    bv->count = 0;
    bv->size = 0;
}

void bv_scan_reset(BitVector *bv)
{
    bv->curr_bit = -1;
}

int bv_eq(BitVector *bv1, BitVector *bv2)
{
    if (bv1 == bv2) {
        return true;
    }

    if (bv1->extends_as_ones != bv2->extends_as_ones) {
        return false;
    }

    u32 *bits = bv1->bits;
    u32 *bits2 = bv2->bits;
    int min_size = min2(bv1->size, bv2->size);
    int word_size = TO_WORD(min_size);
    int ext_word_size = 0;
    int i;

    for (i = 0; i < word_size; i++) {
        if (bits[i] != bits2[i]) {
            return false;
        }
    }
    if (bv1->size > min_size) {
        bits = bv1->bits;
        ext_word_size = TO_WORD(bv1->size);
    }
    else if (bv2->size > min_size) {
        bits = bv2->bits;
        ext_word_size = TO_WORD(bv2->size);
    }
    if (ext_word_size) {
        const u32 expected = (bv1->extends_as_ones ? 0xFFFFFFFF : 0);
        for (i = word_size; i < ext_word_size; i++) {
            if (bits[i] != expected) {
                return false;
            }
        }
    }
    return true;
}

unsigned long bv_hash(BitVector *bv)
{
    unsigned long hash = 0;
    const u32 empty_word = bv->extends_as_ones ? 0xFFFFFFFF : 0;
    int i;
    for (i = TO_WORD(bv->size) - 1; i >= 0; i--) {
        const u32 word = bv->bits[i];
        if (word != empty_word)
            hash = (hash << 1) ^ word;
    }
    return (hash << 1) | bv->extends_as_ones;
}