|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
Packit Service |
20376f |
* a Linking Exception. For full terms see the included COPYING file.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
#ifndef INCLUDE_bitvec_h__
|
|
Packit Service |
20376f |
#define INCLUDE_bitvec_h__
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#include "common.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* This is a silly little fixed length bit vector type that will store
|
|
Packit Service |
20376f |
* vectors of 64 bits or less directly in the structure and allocate
|
|
Packit Service |
20376f |
* memory for vectors longer than 64 bits. You can use the two versions
|
|
Packit Service |
20376f |
* transparently through the API and avoid heap allocation completely when
|
|
Packit Service |
20376f |
* using a short bit vector as a result.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
typedef struct {
|
|
Packit Service |
20376f |
size_t length;
|
|
Packit Service |
20376f |
union {
|
|
Packit Service |
20376f |
uint64_t *words;
|
|
Packit Service |
20376f |
uint64_t bits;
|
|
Packit Service |
20376f |
} u;
|
|
Packit Service |
20376f |
} git_bitvec;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_INLINE(int) git_bitvec_init(git_bitvec *bv, size_t capacity)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
memset(bv, 0x0, sizeof(*bv));
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (capacity >= 64) {
|
|
Packit Service |
20376f |
bv->length = (capacity / 64) + 1;
|
|
Packit Service |
20376f |
bv->u.words = git__calloc(bv->length, sizeof(uint64_t));
|
|
Packit Service |
20376f |
if (!bv->u.words)
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#define GIT_BITVEC_MASK(BIT) ((uint64_t)1 << (BIT % 64))
|
|
Packit Service |
20376f |
#define GIT_BITVEC_WORD(BV, BIT) (BV->length ? &BV->u.words[BIT / 64] : &BV->u.bits)
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_INLINE(void) git_bitvec_set(git_bitvec *bv, size_t bit, bool on)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
uint64_t *word = GIT_BITVEC_WORD(bv, bit);
|
|
Packit Service |
20376f |
uint64_t mask = GIT_BITVEC_MASK(bit);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (on)
|
|
Packit Service |
20376f |
*word |= mask;
|
|
Packit Service |
20376f |
else
|
|
Packit Service |
20376f |
*word &= ~mask;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_INLINE(bool) git_bitvec_get(git_bitvec *bv, size_t bit)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
uint64_t *word = GIT_BITVEC_WORD(bv, bit);
|
|
Packit Service |
20376f |
return (*word & GIT_BITVEC_MASK(bit)) != 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_INLINE(void) git_bitvec_clear(git_bitvec *bv)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
if (!bv->length)
|
|
Packit Service |
20376f |
bv->u.bits = 0;
|
|
Packit Service |
20376f |
else
|
|
Packit Service |
20376f |
memset(bv->u.words, 0x0, bv->length * sizeof(uint64_t));
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_INLINE(void) git_bitvec_free(git_bitvec *bv)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
if (bv->length)
|
|
Packit Service |
20376f |
git__free(bv->u.words);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif
|