sort.h

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002      Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 /*<std-header orig-src='shore' incl-file-exclusion='SORT_H'>
00025 
00026  $Id: sort.h,v 1.30 2010/05/26 01:20:45 nhall Exp $
00027 
00028 SHORE -- Scalable Heterogeneous Object REpository
00029 
00030 Copyright (c) 1994-99 Computer Sciences Department, University of
00031                       Wisconsin -- Madison
00032 All Rights Reserved.
00033 
00034 Permission to use, copy, modify and distribute this software and its
00035 documentation is hereby granted, provided that both the copyright
00036 notice and this permission notice appear in all copies of the
00037 software, derivative works or modified versions, and any portions
00038 thereof, and that both notices appear in supporting documentation.
00039 
00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00044 
00045 This software was developed with support by the Advanced Research
00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00048 Further funding for this work was provided by DARPA through
00049 Rome Research Laboratory Contract No. F30602-97-2-0247.
00050 
00051 */
00052 
00053 #ifndef SORT_H
00054 #define SORT_H
00055 
00056 #include "w_defines.h"
00057 
00058 /*  -- do not edit anything above this line --   </std-header>*/
00059 
00060 // NOTE: you cannot run all the smsh scripts w/o INSTRUMENT_SORT
00061 // turned on.
00062 // We define a method that will allow us to find out
00063 // if INSTRUMENT_SORT is defined; this way the smsh scripts can
00064 // avoid croaking by running things that rely on this being defined.
00065 // It can't be inlined. It's called only by smsh. 
00066 #undef  INSTRUMENT_SORT
00067 extern "C" bool sort_is_instrumentd(); // sort.cpp
00068 
00069 #include <lexify.h>
00070 #include <sort_s.h>
00071 
00072 #ifdef __GNUG__
00073 #pragma interface
00074 #endif
00075 
00076 
00077 struct sort_desc_t;
00078 class run_scan_t;
00079 
00080 /**\addtogroup SSMSORT
00081  *
00082  * The storage manager provides two tools for sorting,
00083  * the class sort_stream_i and the method ss_m::sort_file.
00084  *
00085  * The class sort_stream_i implements
00086  * sorting of <key,elem> pairs with a simple interface.
00087  * It is an adjunct of bulk-loading indexes. One inserts
00088  * <key,elem> pairs into the stream, and then iterates over
00089  * the stream with its sort_stream_i::get_next method to 
00090  * retrieve the pairs in order.  The sort_stream_i uses temporary
00091  * files as necessary to store the data stream.
00092  *
00093  * The storage manager function ss_m::sort_file implements
00094  * a polyphase merge-sort.
00095  *
00096  * Both methods offer a variety of run-time options. 
00097  * The options are specified with different APIs:
00098  * - The sort_stream_i uses \ref ssm_sort::key_info_t to describe keys 
00099  *   and \ref ssm_sort::sort_parm_t to describe behavior options.
00100  * - The ss_m::sort_file uses \ref ssm_sort::sort_keys_t to describe keys 
00101  *   and behavior options.
00102  *
00103  * \note Historical note: The original implementation of the sort_file
00104  * method used the same APIs (for specifying sort behavior and describing
00105  * keys) as sort_stream_i, but that implementation for sort_file was
00106  * inadequate for the needs of the projects using the storage manager
00107  * at the time (viz user-defined key types, 
00108  * marshalling and unmarshalling, etc.). 
00109  * The new implementation is more general, but the sort_stream_i
00110  * has not been rewritten to use the new options- and key- descriptor classes.
00111  *
00112  * See sort_stream_i for details and \ref sort_stream.cpp for an example
00113  * of its use.
00114  * The balance of this section describes the use of ss_m::sort_file and
00115  * its application to bulk-loading.
00116  *
00117  * Sort_file supports: 
00118  * - sorting on one or more keys
00119  * - key types may be 
00120  *    - fundamental (predefined) or user-defined
00121  *    - derived or embedded
00122  * - records being sorted may require marshalling when read from disk 
00123  *   to memory and unmarshalling when written back to disk
00124  * - the result of the sort can be 
00125  *   - a sorted copy of the input file
00126  *   - a file ready for bulk-loading an index to the original file
00127  *
00128  * For all this generality, the sort uses \ref SORTCALLBACK "callbacks" 
00129  * to the server for such things as 
00130  * - key comparisons
00131  * - key derivation
00132  * - object marshalling and unmarshalling
00133  * - producing the final form of keys for output, when the sort key
00134  * is not the key to be loaded into the index (for example consider R-trees:
00135  * a polygon is the index key, but the records are sorted on 
00136  * the polygon's Hilbert value)
00137  *
00138  * \section SORTRUN Runs 
00139  *
00140  * The sort takes as many runs as required to read and sort the
00141  * entire input file, while limiting the amount of memory used.
00142  * The run size is given as an argument to sort_file.
00143  * 
00144  * The sort uses temporary files when the input file contains more records
00145  * than can fit in one run (determined by the run size). 
00146  * These temporary files may be spread across 
00147  * multiple volumes, which is useful if the
00148  * volumes reside on different spindles.
00149  *
00150  * If the entire input file fits into the buffer pool pages of one run,
00151  * much of the complexity of the sort is eliminated, because the copying
00152  * of objects and metadata to scratch files is unnecessary, but for the
00153  * general (polyphase) case, behavioral options describe how the
00154  * writing to scratch files is handled, and these options depend on
00155  * the kind of output desired (see \ref SORTOUTPUT).
00156  *
00157  *
00158  * \section SORTCALLBACK Callbacks 
00159  *
00160  * The sort has to call back to the server for 
00161  *
00162  * - marshalling a record (ssm_sort::MOF):  
00163  *   When a record is first encountered in the 
00164  *   input file, it may be marshalled to produce an in-memory version of the
00165  *   entire object (presumably byte-swapped, pointer-swizzled, etc.). This
00166  *   copy of the record (in the form of an object_t,
00167  *   which is a handle for the record or in-memory representation)
00168  *   is passed to the next callback function (ssm_sort::CSKF).
00169  *   If a marshal function is supplied it is called at least once on
00170  *   every record.
00171  *
00172  * - creating or locating a key (ssm_sort::CSKF): 
00173  *   This callback locates or derives a key for the object.
00174  *   Its result is an skey_t, which is a handle for the derived or
00175  *   embedded key.  This function might have to allocate heap space for
00176  *   the derived keys, in which case sort_file has to deallocate such
00177  *   space, so this callback takes a factory_t for heap management.
00178  *
00179  * - comparing two keys (ssm_sort::CF): The server provides this function to compare
00180  *   two byte streams of some given length each.
00181  *
00182  * - unmarshalling an object (ssm_sort::UMOF): 
00183  *   Before the object is written to the output
00184  *   file after the last run, it may be unmarshalled to produce an on-disk
00185  *   version of the object.  The unmarshal function need not be called
00186  *   on every record. When the output is to be a bulk-loadable file
00187  *   for indexes, unmarshal is not needed. When the output is a copy
00188  *   of the input file, it is sometimes needed:
00189  *   - Case 1, Large object, not deep copy (large-object store will be
00190  *     transferred to the output file so carrying the object has no 
00191  *     effect here) :  No need to unmarshal; 
00192  *     the large object
00193  *     was marshaled in the first place only for the purpose of locating
00194  *     or deriving a sort key.  
00195  *   - Case 2, Large object with deep copy or small object 
00196  *     - Case 2a, Carrying object : Call unmarshal function (UMOF), write
00197  *       its result to the output file.
00198  *     - Case 2b, Not carrying object : No need to unmarshal; pin the original
00199  *       object and copy it to the output file.
00200  *
00201  * \section SORTOUTPUT Behavior and Results of Sort 
00202  *
00203  * Behaviors that can be controlled are the following; these
00204  * behaviors are determined by the contents of the sort_keys_t
00205  * argument to sort_file:
00206  * - The kind of output the sort produces, which can be
00207  *   - a sorted copy of the input file (ssm_sort::sort_keys_t::set_for_file), or
00208  *   - a file suitable for bulk-loading an index (sort_keys_t::set_for_index), 
00209  *   the format of which is:
00210  *     - header contains key in lexicographic format
00211  *     - body contains element
00212  * - whether the original file is to be retained or deleted by the sort
00213  *   (sort_keys_t::set_keep_orig), with variations on these choices
00214  * - how the key is to be located or derived (sort_keys_t::set_sortkey_fixed,
00215      sort_keys_t::set_sortkey_derived, and other attributes of
00216      sort_keys_t)
00217  * - whether the sort is to be stable (sort_keys_t::set_stable)
00218  * - whether the sort is ascending or descending (sort_keys_t::set_ascending)
00219  * - whether the sort is to eliminate duplicate nulls (sort_keys_t::set_null_unique)
00220  * - whether the sort is to eliminate all duplicates (sort_keys_t::set_unique)
00221  * - whether the sort is to call user-defined marshal and unmarshal
00222  *   functions to get/put the resulting data from/to disk
00223  *
00224  * Many behavioral options depend on other options, as discussed below.
00225  *
00226  * \subsection SORTOUTPUTFILE Result is Sorted Copy of Input File
00227  *
00228  * Use ssm_sort::sort_keys_t::set_for_file to create a sorted copy of the input file.
00229  *
00230  * Applicable key description data:
00231  *   - number of keys : >= 1
00232  *   - key access (for each key):
00233  *      - in header or body : a key or its source data 
00234  *          may reside in either header or body of the original record
00235  *      - at fixed location (ssm_sort::sort_keys_t::set_sortkey_fixed): 
00236  *          In all records this key is at the same
00237  *            location in the record (header or body).  User may not provide 
00238  *            a ssm_sort::CSKF for the key (it will not be used, so it is rejected).
00239  *          - aligned : By indicating that a key is adequately aligned in
00240  *          the original record for its key-comparison function (ssm_sort::CF) to 
00241  *          operate on it, the sort function can avoid the work 
00242  *          of copying to an aligned and contiguous buffer before calling the 
00243  *          comparison function (ssm_sort::CF).  (The sort function determines if the
00244  *          key resides entirely on one page; the user does not have to
00245  *          indicate this.)  If the key is in lexicographic format in the
00246  *          original record (after marshalling, if marshalling is used),
00247  *          alignment is immaterial.
00248  *      - derived (ssm_sort::sort_keys_t::set_sortkey_derived) : User must provide a ssm_sort::CSKF callback function to derive the
00249  *            key. The source data may be in
00250  *            the header or body of the record. The ssm_sort::CSKF "knows" the
00251  *            key's offset from the header or body, or receives that
00252  *            information from an argument (key_cookie_t) passed to the
00253  *            callback function.
00254  *   - lexicographic format:  ssm_sort::sort_keys_t::is_lexico indicates that
00255  *          the key is in \ref LEXICOFORMAT "lexigographic format"
00256  *          in the original record, so it can be compared in 
00257  *          segments (if, say, it is spread
00258  *          across page boundaries) and its alignment is immaterial.
00259  *
00260  * Applicable sort behavior options:
00261  * - marshalling : A callback marshal function (MOF) will be called
00262  *           to reformat records from which keys are created. This will
00263  *           be done before the ssm_sort::CSKF is called.
00264  * - ascending : sort in ascending or descending order
00265  * - stable : optionally ensure stable sort
00266  * - unique : eliminate records with duplicate keys
00267  * - null_unique : eliminate records with duplicate null keys
00268  * - keep_orig : optionally delete the original file 
00269  * - carry_obj : optionally duplicate the entire object in the runs
00270  * - deep_copy : optionally copy the large objects
00271  *
00272  * \subsection SORTOUTPUTINDEX Result is Input to Bulk-Load
00273  *
00274  * Applicable key description data:
00275  *   - number of sort keys : only one-key sort is supported
00276  *   - index key derivation: the index key may differ from the sort key,
00277  *     in which case the user provides a callback (ssm_sort::CSKF) function
00278 *       to produce the index key. It must be produced in 
00279  *          \ref LEXICOFORMAT "lexigographic format".
00280  *   - sort key access:
00281  *      - in header or body : a key or its source data 
00282  *          may reside in either header or body of the original record
00283  *      - at fixed location (ssm_sort::sort_keys_t::set_sortkey_fixed): 
00284  *          In all records the key is at the same
00285  *            location in the record (header or body).  User may not provide 
00286  *            a ssm_sort::CSKF for the key (it will not be used, so it is rejected).
00287  *          - aligned : By indicating that a key is adequately aligned in
00288  *          the original record for its key-comparison function (ssm_sort::CF) to 
00289  *          operate on it, the sort function can avoid the work 
00290  *          of copying to an aligned and contiguous buffer before calling the 
00291  *          comparison function (ssm_sort::CF).  (The sort function determines if the
00292  *          key resides entirely on one page; the user does not have to
00293  *          indicate this.)  If the key is in lexicographic format in the
00294  *          original record (after marshalling, if marshalling is used),
00295  *          alignment is immaterial.
00296  *      - derived (ssm_sort::sort_keys_t::set_sortkey_derived) : User must provide a ssm_sort::CSKF callback function to derive the
00297  *            key. The source data may be in
00298  *            the header or body of the record. The ssm_sort::CSKF "knows" the
00299  *            key's offset from the header or body, or receives that
00300  *            information from an argument (key_cookie_t) passed to the
00301  *            callback function.
00302  *       - lexicographic format: if 
00303  *          the key is in \ref LEXICOFORMAT "lexigographic format"
00304  *          in the original record, it can be compared in 
00305  *          segments (if, say, it is spread
00306  *          across page boundaries) and its alignment is immaterial.
00307  *          \b NOTE If it is \b not in 
00308  *          lexicographic format, a ssm_sort::CSKF callback
00309  *          must put it in lexicographic format for the purpose of
00310  *          loading into a B+-Tree (should the sort key be used as the
00311  *          index key), so the sort key must therefore be
00312  *          derived in this case.
00313  *
00314  * Applicable sort behavior options:
00315  * - marshalling : use callback marshal function (MOF) to reformat
00316  *                 records from which keys are created
00317  * - ascending : sort in ascending or descending order
00318  * - stable : may not be set because it might violate RID order  in the
00319  *        event of duplicates (the elements for the pairs with the same
00320  *        key are sorted on the element in the B+-Tree).  If stability
00321  *        is needed, the key should be derived from two keys, or should
00322  *        be a concatenation of multiple keys (either suitable colocated
00323           in the object or derived) that would ensure the stability.
00324  * - unique : eliminate records with duplicate keys
00325  * - null_unique : eliminate records with duplicate null keys
00326  * - keep_orig : n/a
00327  * - carry_obj : n/a
00328  * - deep_copy : n/a
00329  *
00330  * \section SORTKEYS Keys 
00331  *
00332  * Sort keys may be located in the input records or derived from 
00333  * the input records.
00334  * Index keys that are different from the sort key are derived.
00335  *
00336  * When the output is to be a sorted copy of the input file, the
00337  * keys do not appear in the output file except inasmuch as they
00338  * are embedded in the original input records.
00339  * The sort keys in this case may be derived from the record contents, 
00340  * in which case they truly do not appear in the output.
00341  * Multiple keys may be used for the sort, and they may be a combination
00342  * of fixed-location keys and derived keys. See \ref SORTOUTPUTFILE.
00343  *
00344  * When the output is to be a bulk-loadable file, its records takes the form
00345  * header = key, body = element, and sort-file gives the caller no control
00346  * over the elements' contents: they are the record-IDs of the original
00347  * records.  If something other than the record-ID is desired for bulk-loading
00348  * an index, the output can be made to be a sorted copy of the
00349  * original file, with a suitable unmarshal (UMOF) applied.
00350  *
00351  * Only one sort key can be used in this case, but the index key can differ
00352  * differ from the sort key. See \ref SORTOUTPUTINDEX.
00353  *
00354  */
00355 
00356 //
00357 // chunk list for large object buffer
00358 //
00359 /**\cond skip */
00360 struct s_chunk  {
00361 
00362     char* data;
00363     s_chunk* next;
00364 
00365     NORET s_chunk() { data = 0; next = 0; };
00366     NORET s_chunk(w_base_t::uint4_t size, s_chunk* tail) { 
00367               data = new char[size];
00368               next = tail;
00369         };
00370     NORET ~s_chunk() { delete [] data; };
00371 };
00372 
00373 class chunk_mgr_t {
00374 
00375 private:
00376     s_chunk* head;
00377 
00378     void _free_all() { 
00379           s_chunk* curr;
00380           while (head) {
00381         curr = head;
00382         head = head->next;
00383         delete curr;
00384           }
00385       };
00386 
00387 public:
00388 
00389     NORET chunk_mgr_t() { head = 0; };
00390     NORET ~chunk_mgr_t() { _free_all(); };
00391 
00392     void  reset() { _free_all(); head = 0; };
00393 
00394     void* alloc(w_base_t::uint4_t size) {
00395           s_chunk* curr = new s_chunk(size, head);
00396           head = curr;
00397            return (void*) curr->data;
00398       };
00399 };
00400 /**\endcond skip */
00401 
00402 #       define PROTOTYPE(_parms) _parms
00403 
00404 #ifndef PFCDEFINED
00405 
00406 #define PFCDEFINED
00407 typedef int  (*PFC) PROTOTYPE((w_base_t::uint4_t kLen1, 
00408         const void* kval1, w_base_t::uint4_t kLen2, const void* kval2));
00409 
00410 #endif
00411 
00412 /**\class sort_stream_i
00413  * \brief Sorting tool.
00414  * \details
00415  * \ingroup SSMSORT
00416  * Used for bulk-loading indexes but may be used independently.
00417  * After creating an instance of sort_stream_i, you can keep putting
00418  * <key,element> pairs into the stream, which will save the
00419  * records in a temporary persistent store, sort them, and then
00420  * return them in sorted order like an iterator over the temporary
00421  * store.  The temporary store is destroyed upon completion (destruction).
00422  *
00423  * Before you can begin inserting pairs into the stream, you must initialize the
00424  * stream with information about the key on which to sort (where it is to 
00425  * be found, what its length and type are, etc.).
00426  *
00427  * See example \ref sort_stream.cpp
00428  */
00429 class sort_stream_i : public smlevel_top, public xct_dependent_t 
00430 {
00431   typedef ssm_sort::key_info_t key_info_t;
00432   typedef ssm_sort::sort_parm_t sort_parm_t;
00433   typedef ssm_sort::sort_keys_t sort_keys_t;
00434   friend class ss_m;
00435 
00436   public:
00437 
00438     /**\brief Constructor.  If you use this constructor you must use init().
00439     */
00440     NORET    sort_stream_i();
00441     /**\brief Constructor that calls init().
00442      *
00443      * @param[in] k See key_info_t, which describes the keys used to
00444      * sort the data to be inserted.  
00445      * @param[in] s See ssm_sort::sort_parm_t, which describes behavior of the sort.
00446      * @param[in] est_rec_sz  Estimated record size; allows the sort to
00447      * estimate how many items will fit in a page.
00448      */
00449     NORET    sort_stream_i(const key_info_t& k,
00450                 const sort_parm_t& s, uint est_rec_sz=0);
00451 
00452     NORET    ~sort_stream_i();
00453 
00454     /**\brief Return a key-comparison function for the given
00455      * pre-defined key type.
00456      * @param[in] type See key_info_t. 
00457      * @param[in] up If true, the function returns will sort in
00458      * ascending order, if false, in descending order.
00459      */
00460     static PFC  get_cmp_func(key_info_t::key_type_t type, bool up);
00461 
00462     /**\brief Initialize the stream with necessary metadata.
00463      *
00464      * @param[in] k See key_info_t, which describes the keys used to
00465      * sort the data to be inserted.  
00466      * @param[in] s See ssm_sort::sort_parm_t, which describes behavior of the sort.
00467      * @param[in] est_rec_sz  Estimated record size; allows the sort to
00468      * estimate how many items will fit in a page.
00469      */
00470     void    init(const key_info_t& k, const sort_parm_t& s, uint est_rec_sz=0);
00471 
00472     /// Release resources, render unusable.  (Called by destructor if apropos.) 
00473     void    finish();
00474 
00475     /**\brief Insert a key,elem pair into the stream.
00476      * @param[in] key  Key of key,elem pair.
00477      * @param[in] elem Element of key,elem pair.
00478      *
00479      * \note Must be invoked in a transaction, although this is not
00480      * enforced gracefully.
00481      */
00482     rc_t    put(const cvec_t& key, const cvec_t& elem);
00483 
00484     /**\brief Fetch the next key,elem pair from the stream (in sorted order).
00485      * @param[out] key  Key of key,elem pair.
00486      * @param[out] elem Element of key,elem pair.
00487      * @param[out] eof Set to true if no more pairs in the stream.
00488      *
00489      * \note Must be invoked in a transaction, although this is not
00490      * enforced gracefully.
00491      */
00492     rc_t    get_next(vec_t& key, vec_t& elem, bool& eof) ;
00493 
00494     /// Returns true until the first put() call.
00495     bool    is_empty() const { return empty; }
00496 
00497     /// Sort happens at first get_next call, returns false until then.
00498     bool    is_sorted() const { return sorted; }
00499 
00500   private:
00501     void    set_file_sort() { _file_sort = true; _once = false; }
00502     void    set_file_sort_once(sm_store_property_t prop) 
00503                 {
00504                     _file_sort = true; _once = true; 
00505                     _property = prop; 
00506                 }
00507     rc_t    file_put(const cvec_t& key, const void* rec, uint rlen,
00508                 uint hlen, const rectag_t* tag);
00509 
00510     rc_t    file_get_next(vec_t& key, vec_t& elem, 
00511                 w_base_t::uint4_t& blen, bool& eof) ;
00512 
00513     rc_t    flush_run();        // sort and flush one run
00514 
00515     rc_t    flush_one_rec(const record_t *rec, rid_t& rid,
00516                 const stid_t& out_fid, file_p& last_page,
00517                 bool to_final_file);
00518 
00519     rc_t    remove_duplicates();    // remove duplicates for unique sort
00520     rc_t    merge(bool skip_last_pass);
00521 
00522     void    xct_state_changed( xct_state_t old_state, xct_state_t new_state);
00523 
00524     key_info_t        ki;        // key info
00525     sort_parm_t       sp;        // sort parameters
00526     sort_desc_t*      sd;        // sort descriptor
00527 
00528     bool              sorted;        // sorted flag
00529     bool              eof;        // eof flag
00530     bool              empty;        // empty flag
00531     const record_t*   old_rec;    // used for sort unique
00532   
00533     bool              _file_sort;    // true if sorting a file
00534 
00535     int2_t*           heap;           // heap array
00536     int               heap_size;     // heap size
00537     run_scan_t*       sc;           // scan descriptor array    
00538     w_base_t::uint4_t num_runs;      // # of runs for each merge
00539     int               r;           // run index
00540 
00541     chunk_mgr_t       buf_space;    // in-memory storage
00542 
00543     // below vars used for speeding up sort if whole file fits in memory
00544     bool              _once;        // one pass write to result file
00545     sm_store_property_t _property;    // property for the result file
00546 };
00547 
00548 class file_p;
00549 
00550 //
00551 // run scans
00552 //
00553 /**\cond skip */
00554 class run_scan_t {
00555     typedef ssm_sort::key_info_t key_info_t;
00556     typedef ssm_sort::sort_parm_t sort_parm_t;
00557 
00558     lpid_t pid;         // current page id
00559     file_p* fp;         // page buffer (at most fix two pages for unique sort)
00560     int2_t   i;           // toggle between two pages
00561     int2_t   slot;        // slot for current record
00562     record_t* cur_rec;  // pointer to current record
00563     bool eof;         // end of run
00564     key_info_t kinfo;   // key description (location, len, type)
00565     int2_t   toggle_base; // default = 1, unique sort = 2
00566     bool   single;    // only one page
00567     bool   _unique;    // unique sort
00568 
00569 public:
00570     PFC cmp;
00571 
00572     NORET run_scan_t();
00573     NORET ~run_scan_t();
00574 
00575     rc_t init(rid_t& begin, PFC c, const key_info_t& k, bool unique);
00576     rc_t current(const record_t*& rec);
00577     rc_t next(bool& eof);
00578 
00579     bool is_eof()   { return eof; }
00580 
00581     friend bool operator>(run_scan_t& s1, run_scan_t& s2);
00582     friend bool operator<(run_scan_t& s1, run_scan_t& s2);
00583 
00584     const lpid_t& page() const { return pid; }
00585 };
00586 /**\endcond skip */
00587 
00588 
00589 /*<std-footer incl-file-exclusion='SORT_H'>  -- do not edit anything below this line -- */
00590 
00591 #endif          /*</std-footer>*/

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7