--- /dev/null
+#ifndef RESERVOIR_H_MZSA8WJ3
+#define RESERVOIR_H_MZSA8WJ3
+
+#include <stdlib.h>
+
+#include "buf.h"
+
+#ifndef NDEBUG
+#include "notify.h"
+#endif /* NDEBUG */
+
+/* A pool of buf_t */
+
+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
+#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 bufs.
+*/
+reservoir_t reservoir_new(size_t sz);
+
+/* reservoir_grow
+ Increase the storage capacity of the reservoir pointed to by #preservoir
+ by #growby bufs.
+*/
+int reservoir_grow(reservoir_t *preservoir, size_t growby);
+
+/* reservoir_remember
+ Remember #buf, forgetting another buf 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 bufs within #reservoir to #fd, each with a
+ trailing #delim.
+*/
+int reservoir_write(int fd, reservoir_t reservoir, char delim);
+
+/* reservoir_write_meta
+ Write metadata of #reservoir and #samples to fd.
+*/
+int reservoir_write_meta(int fd, reservoir_t reservoir, unsigned long samples, char delim);
+
+#endif /* RESERVOIR_H_MZSA8WJ3 */