networking · advanced · ~40 min
Bit-packed sets; bitwise add/remove with mask.
Build a fixed-capacity set of file-descriptor numbers backed by a bitmap — the same idea as select(2)'s fd_set.
Implement this small API, where each fd is one bit in an array of 32-bit words:
typedef struct fdset fdset_t;
fdset_t *fdset_create(int max_fd); /* tracks fds 0..max_fd inclusive */
void fdset_add(fdset_t *s, int fd);
void fdset_remove(fdset_t *s, int fd);
int fdset_contains(fdset_t *s, int fd); /* 1 if present, else 0 */
int fdset_count(fdset_t *s); /* number of fds currently set */
void fdset_destroy(fdset_t *s);
max_fd: the largest fd the set must hold (>= 0); the set covers 0..max_fd.fd: a file-descriptor number passed to add/remove/contains.fdset_contains returns 1 if fd is in the set, else 0.fdset_count returns how many fds are currently set.s = fdset_create(63)
add 0, 5, 31, 32, 63 -> count == 5, contains(5) == 1, contains(6) == 0
remove 5 -> contains(5) == 0, count == 4
add 0 again -> count stays 4 (idempotent)
add 999 (out of range) -> count stays 4 (ignored)
uint32_t; size the array as (max_fd / 32) + 1 words.select(2) uses an fd_set — a bitmap of file descriptor numbers. Implementing it teaches bitmap math and why epoll superseded select for high-FD-count servers.
max_fd (>=0): largest fd the set holds; fd: an int passed to add/remove/contains.
fdset_contains returns 1/0; fdset_count returns the number of fds set.
Use (max_fd / 32) + 1 words; add/remove/contains are O(1) bit math; out-of-range fds are ignored.
typedef struct fdset fdset_t;
fdset_t *fdset_create(int max_fd);
void fdset_add(fdset_t *s, int fd);
void fdset_remove(fdset_t *s, int fd);
int fdset_contains(fdset_t *s, int fd);
int fdset_count(fdset_t *s);
void fdset_destroy(fdset_t *s);
Indexing past the bitmap on a large fd; using a signed type so the high bit shifts wrong; double-counting in count via a manual popcount with mismatched mask.
add same fd twice — still counted once. remove of absent fd — no-op.
O(1) add/remove/contains. O(words) count.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.