/* bitfield.h — fixed-size bitset over uint64 words with hardware popcount. * * Backs every "set of pieces/blocks" in the engine: a peer's have-set, our own * completed pieces, the in-flight request map, interested/choked flags. The * count()/find operations use __builtin_popcountll and __builtin_ctzll so a * rarest-first picker can scan availability cheaply even for huge torrents. */ #ifndef NAUT_BITFIELD_H #define NAUT_BITFIELD_H #include "naut/common.h" typedef struct naut_bitfield { uint64_t *words; size_t nbits; size_t nwords; } naut_bitfield; naut_err naut_bitfield_init(naut_bitfield *bf, size_t nbits); void naut_bitfield_free(naut_bitfield *bf); NAUT_INLINE bool naut_bitfield_test(const naut_bitfield *bf, size_t i) { return (bf->words[i >> 6] >> (i & 63)) & 1u; } NAUT_INLINE void naut_bitfield_set(naut_bitfield *bf, size_t i) { bf->words[i >> 6] |= (uint64_t)1 << (i & 63); } NAUT_INLINE void naut_bitfield_clear(naut_bitfield *bf, size_t i) { bf->words[i >> 6] &= ~((uint64_t)1 << (i & 63)); } void naut_bitfield_set_all(naut_bitfield *bf); void naut_bitfield_clear_all(naut_bitfield *bf); /* number of set bits */ size_t naut_bitfield_count(const naut_bitfield *bf); /* true when all nbits bits are set (torrent complete) */ bool naut_bitfield_all_set(const naut_bitfield *bf); /* index of first 0 / first 1 bit at or after `from`, or SIZE_MAX if none */ size_t naut_bitfield_find_zero(const naut_bitfield *bf, size_t from); size_t naut_bitfield_find_set(const naut_bitfield *bf, size_t from); /* Load/serialize the BEP-3 wire format: MSB-first within each byte. The wire * order differs from our little-endian word order, so these are not memcpy. */ void naut_bitfield_from_wire(naut_bitfield *bf, const uint8_t *bytes, size_t nbytes); void naut_bitfield_to_wire(const naut_bitfield *bf, uint8_t *bytes, size_t nbytes); #endif /* NAUT_BITFIELD_H */