home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / turbopas / sortkit1.zip / SORTKIT.DOC < prev   
Text File  |  1991-09-16  |  12KB  |  288 lines

  1. *******************************************************************************
  2. *                                   sortKit                                   *
  3. * sortKit Documentation file, Last Update : Sep. 16, 1991.                    *
  4. *******************************************************************************
  5.  
  6.  
  7. *******************************************************************************
  8. *                                Introduction                                 *
  9. *******************************************************************************
  10.  
  11.   This package provides a Turbo-Pascal 6.0 (and 5.5 probably), OOPS Sort
  12.  library that includes an internal sort (quick sort), and external sort
  13.  (merge sort), and a combined internal and external sort (combined sort).
  14.  
  15.   With this package you can create simple to use sort objects that only need
  16.  to define a virtual compare function, to sort data fast, in memory, or 
  17.  huge data files using a fast internal and external sort algorithm. 
  18.  
  19. *******************************************************************************
  20. *                                Internal Sort                                *
  21. *******************************************************************************
  22.  
  23.   The unit quicksrt.pas defines an internal quicksort object. In order to
  24.  perform fast sort, the quickSort object uses an array of pointers to the
  25.  sorted data, and when it needs to swap data elements, it only swaps their
  26.  pointers in the array of pointers. 
  27.  
  28.   In order to define a sort that will sort YOUR data you should define a 
  29.  descendent of the quickSort object that has one virtual function, the 
  30.  compare function. This function receives 2 pointers - a, and b, and 
  31.  returns 1 if the data pointed by a is "bigger" then the data pointed by
  32.  b, it returns 0 if the data pointed by a is "equal" to the data pointed
  33.  by b, and it returns 2, otherwise. 
  34.  
  35.   Let us assume that we want to create a simple textSort object that sorts
  36.  strings. The following definition will explain the way to create such an
  37.  object :
  38.  
  39.  textSort = object(quickSort)
  40.  
  41.         function compare(a, b : pointer) : byte; virtual;
  42.  
  43.  end; { textSort object definition }
  44.  
  45.  function textSort.compare(a, b : pointer) : byte;
  46.  type
  47.         strPtr = ^ string;
  48.  begin
  49.         if (strPtr(a)^ > strPtr(b)^) then
  50.                 compare := 1
  51.         else if (strPtr(a)^ = strPtr(b)^) then
  52.                 compare := 0
  53.         else
  54.                 compare := 2;
  55.  end; {textSort.compare}
  56.  
  57.  In order to use this object we must perform the following steps : 
  58.  
  59.  1. Declare a variable of the required sort type.
  60.  2. Declare a variable of type arrayOfPointersPtr.
  61.  3. Allocate space from the heap to the variables declared in step 2, in the
  62.     amount of numberOfElementsToSort * sizeOf(pointer).
  63.  4. Assign to the array defined, the pointers to the data elements to be sorted.
  64.  5. Initialize the sort object.
  65.  6. Call the sort object's doYourJob method.
  66.  
  67.  Let us assume that we want to sort an array of 200 strings that we have in
  68.  memory, in a string array defined as :
  69.  
  70.  var
  71.         stringArray : array [1.200] of string;
  72.  
  73.  We will use the following code :
  74.  
  75.  var
  76.         myInternalSort : textSort;                      { step 1 }
  77.         pointers       : arrayOfPointersPtr;            { step 2 }
  78.  begin
  79.         getmem(pointers, 200 * sizeOf(pointer));        { step 3 }
  80.         {$R-} {This is important !, otherwise we will get range errors }
  81.         for i := 1 to 200 do 
  82.                 pointers[i] := @stringArray[i];         { step 4 }
  83.         myInternalSort.init(200, pointers, 256);        { step 5 }
  84.         myInternalSort.doYourJob;                       { step 6 }
  85.   ... { some more code .. }
  86.  
  87.   Notice - At the end of this procedure stringArray is NOT sorted, but 
  88.            pointers is a pointer to a sorted array of pointers. If we
  89.            would like to print the sorted array we will use a procedure 
  90.            such as :
  91.  
  92.         for i := 1 to 200 do
  93.                 writeln(strPtr(pointers[i])^);
  94.  
  95. *******************************************************************************
  96. *                                External Sort                                *
  97. *******************************************************************************
  98.  
  99.   The unit mergsort.pas defines an external mergesort object. This sort is
  100.  used as the basis of file sort routines.
  101.  
  102.   In order to define a sort that will sort YOUR data files you should define
  103.  a descendent of mergeSort that has one virtual function, the compare
  104.  function. This function compares to pointer variables named block1 and
  105.  block2 and returns 1 if the data pointed by block1 is "bigger" then the
  106.  data pointed by block2, 0 if the data pointed by block1 is "equal" to the
  107.  data pointed by block2, and 2, otherwise.
  108.  
  109.   Let us assume that we have a file of myRecord, where myRecord is defined
  110.  as : 
  111.  
  112.  type
  113.         myRecord = record
  114.                 myNum : word;
  115.                 myStatus : integer;
  116.                 myName : string[20];
  117.         end; { myRecord definition }
  118.  
  119.   We will have to use the following code in order to define a sort object 
  120.  that will sort according to the myNum field : 
  121.  
  122.  type
  123.         myExternalSort = object(mergeSort)
  124.  
  125.                 function compare : byte; virtual;
  126.  
  127.         end; { myExternalSort object definition }
  128.  
  129.  function myExternalSort.compare : byte;
  130.  type
  131.         myRecordPtr = ^ myRecord;
  132.  begin
  133.         if (myRecordPtr(block1)^.myNum > myRecordPtr(block2)^.myNum) then
  134.                 compare := 1
  135.         else if (myRecordPtr(block1)^.myNum = myRecordPtr(block2)^.myNum) then
  136.                 compare := 0
  137.         else
  138.                 compare := 2;
  139.  end; {myExternalSort.compare}
  140.  
  141.  In order to use this object we must perform the following steps :
  142.   
  143.  1. Declare a variable of the required sort type.
  144.  2. Initialize the sort object.
  145.  3. Call the sort object's doYourJob method.
  146.  4. Call the sort object's done destructor.
  147.  
  148.  Let us assume we want to sort the file ORGFIL.DTA, which is a file of myRecord,
  149.  to the file SRTFIL.DTA. The code we will use will be :
  150.  
  151.  var
  152.         fileSort : myExternalSort;                      { step 1 }
  153.  begin
  154.         fileSort.init('ORGFIL.DTA', sizeOf(myRecord), 
  155.                       '', 'SRTFIL.DTA');                { step 2 }
  156.         fileSort.doYourJob;                             { step 3 }
  157.         fileSort.done;                                  { step 4 }
  158.   .. { some more code .. }
  159.  
  160.   Notice - The 3rd parameter of the init constructor is the temporary
  161.  path to use during the sort. If we have a RAM disk, large enough to hold
  162.  two files the size of the original file, in drive d:, we can replace
  163.  step 2 with the following code :
  164.  
  165.         fileSort.init('ORGFIL.DTA', sizeOf(myRecord), 
  166.                       'D:\', 'SRTFIL.DTA');             { step 2 }
  167.  
  168.  And the sort will be much faster. Notice - The output file will be on
  169.  drive D:\ at the end of the sort.
  170.  
  171. *******************************************************************************
  172. *                                Combined Sort                                *
  173. *******************************************************************************
  174.  
  175.   A combined sort is an external merge sort that uses an internal quick sort     
  176.  object descendent at the first phase of the sort. Because of this feature
  177.  a combined sort is faster then then the "classic" merge sort - internal sort 
  178.  is fast, there are fewer passes on the temporary files, and thus less I/O
  179.  operations are performed. The only problem with combined sort is the added
  180.  complexity to define and code it. I have tried to minimize this problem
  181.  in the implementation of the combinedSort object provided in the combsort.pas
  182.  unit file. 
  183.  
  184.   Let us use the same example we used in the merge sort section, and try to
  185.  sort the same data file using a combined sort. In order to achieve this
  186.  goal we will have to follow the followin procedure : 
  187.  
  188.  1. Declare a variable of the required sort type, where the sort object is
  189.     a descendent of the combinedSort object, and it is defined the same way
  190.     the merge sort descendent was defined.
  191.  2. Declare a pointer internal sort variable, which performs a compare 
  192.     function similar to the external sort compare function.
  193.  3. Initialize the internal sort, with a nil parameter for the array of 
  194.     pointers.
  195.  4. Initalize the variable declared in step 1 passing the variable declared
  196.     in step 2 as a parameter.
  197.  5. Call the external sort doYourJob method.
  198.  6. Call the external sort done destructor.
  199.  
  200.  Given the same example as the merge sort file the code needed will be :
  201.  
  202.  type
  203.         myInternalSortPtr = ^ myInternalSort;
  204.         myInternalSort = object(quickSort)
  205.  
  206.                 function compare(a, b : pointer) : byte; virtual;
  207.  
  208.         end; { myInternalSort object definition }
  209.  
  210.         myCombinedSort = object(combinedSort)
  211.  
  212.                 function compare : byte; virtual;
  213.  
  214.         end; { myCombinedSort object definition }
  215.  
  216.  var
  217.         misp : myInternalSortPtr;
  218.         mcs  : myCombinedSort;
  219.  
  220.  function doCompare(p1, p2 : pointer) : byte; 
  221.  { this function will compare for both the internal and external sorts }
  222.  type
  223.         myRecordPtr = ^ myRecord;
  224.  begin
  225.         if (myRecordPtr(p1)^.myNum > myRecordPtr(p2)^.myNum) then
  226.                 doCompare := 1
  227.         else if (myRecordPtr(p1)^.myNum = myRecordPtr(p2)^.myNum) then
  228.                 doCompare := 0
  229.         else
  230.                 doCompare := 2;
  231.  end; {doCompare}
  232.  
  233.  function myCombinedSort.compare : byte;
  234.  begin
  235.         compare := doCompare(block1, block2);
  236.  end; {myCombinedSort.compare}
  237.  
  238.  function myInternalSort.compare(a, b : pointer) : byte;
  239.  begin
  240.         compare := doCompare(a, b);
  241.  end; {myInternalSort.compare}
  242.  
  243.  begin
  244.         new(misp, init(1, nil, sizeof(myRecord))); 
  245.         { notice that the first  parameter is not important, put 1 always }
  246.         { notice that the second parameter is not important, put nil }
  247.         myCombinedSort.init('ORGFIL.DTA', sizeOf(myRecord), 
  248.                             'D:\', 'SRTFIL.DTA', misp);
  249.         myCombinedSort.doYourJob;
  250.         myCombinedSort.done;
  251.         ... { rest of code .. }
  252.  
  253. *******************************************************************************
  254. *                                  Warranty                                   *
  255. *******************************************************************************
  256.  
  257.   There is no warranty what so ever, The units and docs. are supplied as is,
  258.  The author (Loewy Ron), is not, and will not be responsible for any damages,
  259.  lost profits, or inconveniences caused by the use, or inability to
  260.  use this unit. The use of the unit is at your own risk. By using the unit
  261.  you agree to this.
  262.  
  263. *******************************************************************************
  264. *                                   General                                   *
  265. *******************************************************************************
  266.  
  267.   sortKit is copyrighted by myself, (c) Loewy Ron, 1991. If you find sortKit
  268.  valuable, please register your copy. Notice - sortKit is not a free or 
  269.  public domain package. It is a shareware package, please refer to the
  270.  supplied order form in the file ORDER.TXT.
  271.  
  272. *******************************************************************************
  273. *                                   Contact                                   *
  274. *******************************************************************************
  275.  
  276.   You can contact me on what-ever you want to at my address at :
  277.  
  278.           Loewy Ron,                            Loewy Ron
  279.           9 Haneveem st.            Or          20 Smolanskin st.
  280.           Herzeliya, 46465,                     Haifa, 34366,
  281.           Israel.                               Israel.
  282.  
  283. *******************************************************************************
  284. *                                   Credits                                   *
  285. *******************************************************************************
  286.  
  287.   Turbo-Pascal is a copyright of Borland International.
  288.