Coverage Report

Created: 2023-06-07 06:32

/src/libgit2/src/util/bitvec.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) the libgit2 contributors. All rights reserved.
3
 *
4
 * This file is part of libgit2, distributed under the GNU GPL v2 with
5
 * a Linking Exception. For full terms see the included COPYING file.
6
 */
7
#ifndef INCLUDE_bitvec_h__
8
#define INCLUDE_bitvec_h__
9
10
#include "common.h"
11
12
/*
13
 * This is a silly little fixed length bit vector type that will store
14
 * vectors of 64 bits or less directly in the structure and allocate
15
 * memory for vectors longer than 64 bits.  You can use the two versions
16
 * transparently through the API and avoid heap allocation completely when
17
 * using a short bit vector as a result.
18
 */
19
typedef struct {
20
  size_t length;
21
  union {
22
    uint64_t *words;
23
    uint64_t bits;
24
  } u;
25
} git_bitvec;
26
27
GIT_INLINE(int) git_bitvec_init(git_bitvec *bv, size_t capacity)
28
0
{
29
0
  memset(bv, 0x0, sizeof(*bv));
30
31
0
  if (capacity >= 64) {
32
0
    bv->length = (capacity / 64) + 1;
33
0
    bv->u.words = git__calloc(bv->length, sizeof(uint64_t));
34
0
    if (!bv->u.words)
35
0
      return -1;
36
0
  }
37
38
0
  return 0;
39
0
}
40
41
0
#define GIT_BITVEC_MASK(BIT) ((uint64_t)1 << (BIT % 64))
42
0
#define GIT_BITVEC_WORD(BV, BIT) (BV->length ? &BV->u.words[BIT / 64] : &BV->u.bits)
43
44
GIT_INLINE(void) git_bitvec_set(git_bitvec *bv, size_t bit, bool on)
45
0
{
46
0
  uint64_t *word = GIT_BITVEC_WORD(bv, bit);
47
0
  uint64_t mask = GIT_BITVEC_MASK(bit);
48
49
0
  if (on)
50
0
    *word |= mask;
51
0
  else
52
0
    *word &= ~mask;
53
0
}
54
55
GIT_INLINE(bool) git_bitvec_get(git_bitvec *bv, size_t bit)
56
0
{
57
0
  uint64_t *word = GIT_BITVEC_WORD(bv, bit);
58
0
  return (*word & GIT_BITVEC_MASK(bit)) != 0;
59
0
}
60
61
GIT_INLINE(void) git_bitvec_clear(git_bitvec *bv)
62
0
{
63
0
  if (!bv->length)
64
0
    bv->u.bits = 0;
65
0
  else
66
0
    memset(bv->u.words, 0x0, bv->length * sizeof(uint64_t));
67
0
}
68
69
GIT_INLINE(void) git_bitvec_free(git_bitvec *bv)
70
0
{
71
0
  if (bv->length)
72
0
    git__free(bv->u.words);
73
0
}
74
75
#endif