StreamIO functor
functor StreamIO ( ... ) : STREAM_IO (* OPTIONAL *)
The optional StreamIO functor provides a way to build a Stream I/O layer on top of an arbitrary Primitive I/O implementation. For example, given an implementation of readers and writers for pairs of integers, one can define streams of pairs of integers.
structure PrimIO : PRIM_IO
structure Vector : MONO_VECTOR
structure Array : MONO_ARRAY
sharing type PrimIO.elem = Vector.elem = Array.elem
sharing type PrimIO.vector = Vector.vector = Array.vector
sharing type PrimIO.array = Array.array
val someElem : PrimIO.elem
structure PrimIO : PRIM_IO
val someElem : PrimIO.elem
ImperativeIO,MONO_ARRAY,MONO_VECTOR,PrimIO,PRIM_IO,STREAM_IO
The Vector and Array structures provide vector and array operations for manipulating the vectors and arrays used in PrimIO and StreamIO. The element someElem is used to initialize buffer arrays; any element will do.
The types instream and outstream in the result of the StreamIO functor must be abstract.
Implementation note:
Here are some suggestions for efficient performance:
- Operations on the underlying readers and writers (
readVec, etc.) are expected to be expensive (involving a system call, with context switch).- Small input operations can be done from a buffer; the
readVecorreadVecNBoperation of the underlying reader can replenish the buffer when necessary.- Each reader may provide only a subset of
readVec,readVecNB,block,canInput, etc. An augmented reader that provides more operations can be constructed usingPrimIO.augmentReader, but it may be more efficient to use the functions directly provided by the reader, instead of relying on the constructed ones. The same applies to augmented writers.- Keep the position of the beginning of the buffer on a multiple-of-
chunkSizeboundary, and do read or write operations with a multiple-of-chunkSizenumber of elements.- For very large
inputAllorinputNoperations, it is (somewhat) inefficient to read onechunkSizeat a time and then concatenate all the results together. Instead, it is good to try to do the read all in one large system call; that is,readVec(n). In a typical implementation ofreadVec, this requires pre-allocating a vector of size n. IninputAll, however, the size of the vector is not known a priori and if the argument toinputNis large, the allocation of a much-too-large buffer is wasteful. Therefore, for large input operations, query the remaining size of the reader usingavail, and try to read that much. But one should also keep things rounded to the nearestchunkSize.- The use of
availto try to do (large) read operations of just the right size will be inaccurate on translated readers. But this inaccuracy can be tolerated: if the translation is anything close to 1-1,availwill still provide a very good hint about the order-of-magnitude size of what remains to be read.- Similar suggestions apply to very large output operations. Small outputs go through a buffer; the buffer is written with
writeArr. Very large outputs can be written directly from the argument string usingwriteVec.- A lazy functional input stream can (should) be implemented as a sequence of immutable (vector) buffers, each with a mutable
refto the next ``thing,'' which is either another buffer, the underlying reader, or an indication that the stream has been truncated.- The
inputfunction should return the largest sequence that is most convenient. Usually this means ``the remaining contents of the current buffer.''- To support non-blocking input, use
readVecNBif it exists, otherwise docanInputfollowed (if appropriate) byreadVec.- To support blocking input, use
readVecif it exists, otherwise doreadVecNBfollowed (if it would block) byblock. and then anotherreadVecNB.- To support lazy functional streams,
readArrandreadArrNBare not useful. If necessary,readVecshould be synthesized fromreadArrandreadVecNBfromreadArrNB.writeArrshould, if necessary, be synthesized fromwriteVecand vice versa. Similarly forwriteArrNBandwriteVecNB.
Generated April 12, 2004
Last Modified May 10, 1996
Comments to John Reppy.
This document may be distributed freely over the internet as long as the copyright notice and license terms below are prominently displayed within every machine-readable copy.
|
Copyright © 2004 AT&T and Lucent Technologies. All rights reserved.
Permission is granted for internet users to make one paper copy for their
own personal use. Further hardcopy reproduction is strictly prohibited.
Permission to distribute the HTML document electronically on any medium
other than the internet must be requested from the copyright holders by
contacting the editors.
Printed versions of the SML Basis Manual are available from Cambridge
University Press.
To order, please visit
www.cup.org (North America) or
www.cup.cam.ac.uk (outside North America). |