#ifndef RESERVOIR_H_MZSA8WJ3 #define RESERVOIR_H_MZSA8WJ3 #include #include "buf.h" #ifndef NDEBUG #include "notify.h" #endif /* NDEBUG */ /* A size-limited pool of buf_t entries. When the reservoir is filled with more entries than there is room for, some spill away and are lost. */ typedef struct reservoir_ { size_t reservoir_sz; /* allocated slots */ size_t reservoir_used; /* slots filled */ unsigned long reservoir_tally; /* total number of items remembered */ buf_t reservoir[]; } *reservoir_t; #ifndef NDEBUG /* For debugging, dump an entire reservoir's contents. */ #define D_RESERVOIR(__r__) do {\ size_t i;\ NOTIFY_DEBUG("reservoir:%p sz: %zu used:%zu tally:%zu", (__r__), (__r__)->reservoir_sz, (__r__)->reservoir_used, (__r__)->reservoir_tally);\ for (i = 0; i < (__r__)->reservoir_sz; i++) {\ D_BUF("reservoir[%zu] ", (__r__)->reservoir[i], i);\ }\ } while (0) #else /* NDEBUG */ #define D_RESERVOIR(...) #endif /* NDEBUG */ /* reservoir_new Allocate and return a new reservoir capable of holding #sz buf_t entries. */ reservoir_t reservoir_new(size_t sz); /* reservoir_del Deallocate the reservoir pointed to by #preservoir. */ void reservoir_del(reservoir_t *preservoir); /* reservoir_grow Increase the storage capacity of the reservoir pointed to by #preservoir by #growby entries. */ int reservoir_grow(reservoir_t *preservoir, size_t growby); /* reservoir_remember Remember #buf, forgetting (and freeing) another buf_t chosen at random if the reservoir pointed to by #preservoir is already full to capacity. */ void reservoir_remember(reservoir_t reservoir, buf_t buf); /* reservoir_write Write the contents of the buf_t entries within #reservoir to #fd, each with a trailing #delim character. */ int reservoir_write(int fd, reservoir_t reservoir, char delim); /* reservoir_write_meta Write metadata about #reservoir and #samples to fd. */ int reservoir_write_meta(int fd, reservoir_t reservoir, unsigned long samples, char delim); #endif /* RESERVOIR_H_MZSA8WJ3 */