-/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
\f
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
has been written to, but this is only updated after a flush.
read_pos and write_pos in principle should be equal, but this is only true
when rw_active is SCM_PORT_NEITHER.
-*/
+
+ ENHANCE-ME - output blocks:
+
+ The current code keeps an output string as a single block. That means
+ when the size is increased the entire old contents must be copied. It'd
+ be more efficient to begin a new block when the old one is full, so
+ there's no re-copying of previous data.
+
+ To make seeking efficient, keeping the pieces in a vector might be best,
+ though appending is probably the most common operation. The size of each
+ block could be progressively increased, so the bigger the string the
+ bigger the blocks.
+
+ When `get-output-string' is called the blocks have to be coalesced into a
+ string, the result could be kept as a single big block. If blocks were
+ strings then `get-output-string' could notice when there's just one and
+ return that with a copy-on-write (though repeated calls to
+ `get-output-string' are probably unlikely).
+
+ Another possibility would be to extend the port mechanism to let SCM
+ strings come through directly from `display' and friends. That way if a
+ big string is written it can be kept as a copy-on-write, saving time
+ copying and maybe saving some space. */
+
scm_t_bits scm_tc16_strport;
#define SCM_WRITE_BLOCK 80
/* ensure that write_pos < write_end by enlarging the buffer when
- necessary. update read_buf to account for written chars. */
+ necessary. update read_buf to account for written chars.
+
+ The buffer is enlarged by 1.5 times, plus SCM_WRITE_BLOCK. Adding just a
+ fixed amount is no good, because there's a block copy for each increment,
+ and that copying would take quadratic time. In the past it was found to
+ be very slow just adding 80 bytes each time (eg. about 10 seconds for
+ writing a 100kbyte string). */
+
static void
st_flush (SCM port)
{
if (pt->write_pos == pt->write_end)
{
- st_resize_port (pt, pt->write_buf_size + SCM_WRITE_BLOCK);
+ st_resize_port (pt, pt->write_buf_size * 3 / 2 + SCM_WRITE_BLOCK);
}
pt->read_pos = pt->write_pos;
if (pt->read_pos > pt->read_end)