diff --git a/tpie/include/ami_merge.h b/tpie/include/ami_merge.h index ca195d9c9..40c53a17c 100644 --- a/tpie/include/ami_merge.h +++ b/tpie/include/ami_merge.h @@ -8,7 +8,7 @@ // lower level streams will use appropriate levels of buffering. This // will be more critical for parallel disk implementations. // -// $Id: ami_merge.h,v 1.2 1994-08-31 19:16:05 darrenv Exp $ +// $Id: ami_merge.h,v 1.3 1994-09-16 13:24:48 darrenv Exp $ // #ifndef _AMI_MERGE_H #define _AMI_MERGE_H @@ -210,15 +210,79 @@ template AMI_err AMI_partition_and_merge(AMI_STREAM *instream, AMI_STREAM *outstream, M *mobj) { + AMI_err ae; + off_t len; + size_t sz_avail, sz_stream; + // Figure out how much memory we've got to work with. + if (MM_manager.available(&sz_avail) != MM_ERROR_NO_ERROR) { + return AMI_ERROR_MM_ERROR; + } + + // If the whole input stream can fit in main memory, then load it + // and call the bottoming out function. + + len = instream->stream_len(); + + if ((len * sizeof(T)) <= sz_avail) { + MM_ptr mm_stream; + + if (!(mm_stream = MM_manager->alloc(len * sizeof(T)))) { + return AMI_ERROR_MM_ERROR; + } + + if ((ae = instream->read_array(mm_stream, &len1)) != + AMI_ERROR_NO_ERROR) { + return ae; + } + + tp_assert(len1 = len, "Did not read the right amount; " + "Allocated space for " << len << ", read " << len1 << '.'); + + if ((ae = (*mm_operate)(mm_stream, len)) != + AMI_ERROR_NO_ERROR) { + return ae; + } + + if ((ae = outstream->write_array(mm_stream, len)) != + AMI_ERROR_NO_ERROR) { + return ae; + } + + MM_manager->free(mm_stream); + + return AMI_ERROR_NO_ERROR; + + } else { + + // It won't all fit, so we have to recurse. + + tp_assert(0, "Recursive part not implemented yet."); + + return AMI_ERROR_INSUFFICIENT_MAIN_MEMORY; + } +}; + + +#if 0 // How much memory do we need for each substream? + if ((ae = instream->main_memory_usage(&sz_stream, + MM_STREAM_USAGE_SUBSTREAM)) != + AMI_ERROR_NO_ERROR) { + return ae; + } + // Determine how many substreams we can merge at a time. + substream_arity = sz_avail / sz_stream; + // Determine the depth of recursion. What is important is whether // it is even or odd, since that will determine whether we start // out going to the output stream or to the shadow stream. + + // If the recursion depth exceeds 1 the create a shadow stream as // large as the input stream. @@ -234,6 +298,7 @@ AMI_err AMI_partition_and_merge(AMI_STREAM *instream, return AMI_ERROR_NO_ERROR; }; +#endif #endif // _AMI_MERGE_H diff --git a/tpie/include/mm_base.h b/tpie/include/mm_base.h index 511c22df7..777797d9f 100644 --- a/tpie/include/mm_base.h +++ b/tpie/include/mm_base.h @@ -4,11 +4,13 @@ // Author: Darren Erik Vengroff // Created: 5/30/94 // -// $Id: mm_base.h,v 1.2 1994-08-31 19:28:03 darrenv Exp $ +// $Id: mm_base.h,v 1.3 1994-09-16 13:25:13 darrenv Exp $ // #ifndef _MM_BASE_H #define _MM_BASE_H +#include + // MM Error codes enum MM_err { MM_ERROR_NO_ERROR = 0, @@ -25,13 +27,46 @@ enum MM_stream_usage { // Amount currently in use. MM_STREAM_USAGE_CURRENT, // Max amount that will ever be used. - MM_STREAM_USAGE_MAXIMUM + MM_STREAM_USAGE_MAXIMUM, + // Maximum additional amount used by each substream created. + MM_STREAM_USAGE_SUBSTREAM }; +// The base class for pointers into memory being managed by memory +// managers. In a uniprocessor, these objects will simply contain +// pointers. In multiprocessors, they will be more complicated +// descriptions of the layout of memory. +class MM_ptr_base +{ +public: + // This should return 1 to indicate a valid pointer and 0 to + // indicate an invalid one. It is usefull for tests and + // assertions. + virtual operator int (void) = 0; +}; // The base class for all memory management objects. -class MM_base_manager +class MM_manager_base { +public: + // How much is currently available. + virtual MM_err available(size_t *sz_a) = 0; + // Allocate some space. + virtual MM_err alloc(size_t req, MM_ptr_base *p) = 0; + // Free space. + virtual MM_err free(MM_ptr_base *p) = 0; + + // Registration for main memory usage that cannot be allocated + // directly through the memory manager. Use of these is + // discouraged, but sometimes unavoidable, such as in accounting + // for space used in the buffer cache. + + virtual MM_err register_allocation(size_t sz) = 0; + virtual MM_err register_deallocation(size_t sz) = 0; + }; +// A pointer to the one and only memory manager. +extern MM_manager_base *mm_manager; + #endif // _MM_BASE_H diff --git a/tpie/lib/src/Makefile.in b/tpie/lib/src/Makefile.in index 35c1015fa..177308a12 100644 --- a/tpie/lib/src/Makefile.in +++ b/tpie/lib/src/Makefile.in @@ -1,6 +1,6 @@ # Copyright (c) 1994 Darren Erik Vengroff -# $Id: Makefile.in,v 1.3 1994-08-31 19:37:31 darrenv Exp $ +# $Id: Makefile.in,v 1.4 1994-09-16 13:25:54 darrenv Exp $ # Makefile for TPIE libraries. @@ -48,14 +48,16 @@ $(UP_TO_DATE): $(LIBRARY) $(AR) $(ARFLAGS) $@ $< $(LIBRARY): $(LIBRARY)(logstream.o) $(LIBRARY)(tpie_log.o) \ - $(LIBRARY)(mm_register.o) $(LIBRARY)(ami_device.o) \ - $(LIBRARY)(ami_single.o) + $(LIBRARY)(mm_single.o) $(LIBRARY)(ami_device.o) \ + $(LIBRARY)(ami_single.o) $(LIBRARY)(mm_base.o) $(LIBRARY)(logstream.o): logstream.o $(LIBRARY)(tpie_log.o): tpie_log.o -$(LIBRARY)(mm_register.o): mm_register.o +$(LIBRARY)(mm_base.o): mm_base.o + +$(LIBRARY)(mm_single.o): mm_single.o $(LIBRARY)(ami_device.o): ami_device.o