@@@ man wip
[mLib] / mem / growbuf.3
diff --git a/mem/growbuf.3 b/mem/growbuf.3
new file mode 100644 (file)
index 0000000..c31f27c
--- /dev/null
@@ -0,0 +1,98 @@
+.\" -*-nroff-*-
+.TH growbuf 3 "9 March 2024" "Straylight/Edgeware" "mLib utilities library"
+.\" @GROWBUF_SIZE
+.\" @GROWBUF_EXTEND
+.\" @GROWBUF_REPLACE
+.
+.SH NAME
+growbuf \- extend buffers efficiently
+.
+.SH SYNOPSIS
+.nf
+.B "#include <mLib/growbuf.h>"
+
+.BI "GROWBUF_SIZE(size_t " sz ", size_t " want ", " \c
+.BI "size_t " init ", size_t " granule ");"
+
+.ds mT \fBGROWBUF_EXTEND(
+.BI "\*(mTarena *" a ", " type " *" buf ", size_t " sz ", size_t " want ","
+.BI "\h'\w'\*(mT'u'size_t " init ", size_t " granule ");"
+.ds mT \fBGROWBUF_REPLACE(
+.BI "\*(mTarena *" a ", " type " *" buf ", size_t " sz ", size_t " want ","
+.BI "\h'\w'\*(mT'u'size_t " init ", size_t " granule ");"
+.fi
+.
+.SH DESCRIPTION
+The
+.B "<mLib/growbuf.h>"
+header file defines macros useful for dynamically resizing buffers.
+.PP
+The situation envisaged is a buffer, at address
+.IR buf ,
+with space to hold
+.I sz
+objects each of size
+.IR granule ;
+but it has become necessary to store
+.I want
+objects in the buffer.
+If the current size
+.I sz
+is zero, then the buffer pointer
+.I buf
+may be null;
+otherwise, it is assumed to have been allocated from the arena
+.IR a .
+The size
+.I init
+is a suggested minimal nonzero size, again counting objects of size
+.IR granule .
+.PP
+The
+.B GROWBUF_SIZE
+macro merely adjusts
+.I sz
+so that it is at least as large as
+.IR want ;
+it is
+.I assumed
+on entry that
+.IR sz "\ <\ " want ;
+nothing especially terrible will happen if this is not the case,
+but unnecessary work will take place,
+and
+.I sz
+will be left nonzero if it was previously zero,
+even if
+.IR want "\ =\ 0."
+.B GROWBUF_SIZE
+arranges to increase buffer sizes in a geometric progression
+so as to minimize reallocation and copying overheads \(en
+the number of reallocations will be
+at most logarithmic in the final size
+and each byte is copied an (amortized) constant number of times.
+.PP
+The
+.B GROWBUF_EXTEND
+macro will additionally resize the buffer,
+preserving its contents,
+and adjusting
+.I buf
+to point to its new location;
+if
+.I want
+\(<=
+.I sz
+then nothing happens.
+The
+.B GROWBUF_REPLACE
+macro is similar, except that it
+.I discards
+the existing buffer contents if the buffer needs to be adjusted.
+.
+.SH "SEE ALSO"
+.BR arena (3),
+.BR mLib (3).
+.
+.SH AUTHOR
+Mark Wooding, <mdw@distorted.org.uk>