Naut/include/naut/bitfield.h
ookami125 2178d6a70c Initial commit: Naut-Torrent — from-scratch 10 GbE BitTorrent client
A maintainable, extensible BitTorrent client (C11, Linux/io_uring) targeting
10 GbE saturation. All torrent functionality is built from scratch; liburing
is the only linked third-party dependency on the data path.

Implements Phases 1-7 of the roadmap:
- core: page-aligned buffer pool, MPMC/Treiber queues, bitfields, worker pool
- crypto: SHA-1/256 (SHA-NI + scalar), Merkle (BEP-52), RC4 (MSE)
- bencode/metainfo: zero-copy parser, v1/v2/hybrid .torrent + magnet
- peer: sans-IO wire codec, MSE/PE handshake state machine, BEP-10, ut_metadata, PEX
- piece/storage: block-level multi-peer engine, rarest-first + endgame,
  per-file completion events + single-file relocate (move-as-you-finish)
- tracker/dht: HTTP + UDP (BEP-15) trackers, BEP-5 KRPC iterative lookup
- platform: io_uring reactor (SQPOLL, registered buffers, SEND_ZC)
- surface: versioned RPC, native plugin ABI, sandboxed Lua scripting, nautd/nautctl

Verified against libtorrent (single/multi/hybrid, MSE, magnet-via-DHT, swarm);
unit + interop tests green; ASan/UBSan/TSan clean. Scripting reference in
docs/scripting.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:12:00 -04:00

49 lines
1.9 KiB
C

/* 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 */