ami_sort.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /****************************************************************************
  2. *
  3. * MODULE: iostream
  4. *
  5. * COPYRIGHT (C) 2007 Laura Toma
  6. *
  7. *
  8. * Iostream is a library that implements streams, external memory
  9. * sorting on streams, and an external memory priority queue on
  10. * streams. These are the fundamental components used in external
  11. * memory algorithms.
  12. * Credits: The library was developed by Laura Toma. The kernel of
  13. * class STREAM is based on the similar class existent in the GPL TPIE
  14. * project developed at Duke University. The sorting and priority
  15. * queue have been developed by Laura Toma based on communications
  16. * with Rajiv Wickremesinghe. The library was developed as part of
  17. * porting Terraflow to GRASS in 2001. PEARL upgrades in 2003 by
  18. * Rajiv Wickremesinghe as part of the Terracost project.
  19. *
  20. * This program is free software; you can redistribute it and/or modify
  21. * it under the terms of the GNU General Public License as published by
  22. * the Free Software Foundation; either version 2 of the License, or
  23. * (at your option) any later version.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  28. * General Public License for more details.
  29. * **************************************************************************/
  30. #ifndef _AMI_SORT_H
  31. #define _AMI_SORT_H
  32. #include "ami_sort_impl.h"
  33. #define SORT_DEBUG if(0)
  34. /* ---------------------------------------------------------------------- */
  35. // A version of AMI_sort that takes an input streamof elements of type
  36. // T, creates an output stream and and uses the < operator to sort
  37. // instream is allocated; *outstream is created
  38. // template<class T>
  39. // AMI_err
  40. // AMI_sort(AMI_STREAM<T> *instream, AMI_STREAM<T> **outstream) {
  41. // cout << "Not implemented yet!\n";
  42. // exit(1);
  43. // return AMI_ERROR_NO_ERROR;
  44. // }
  45. /* ---------------------------------------------------------------------- */
  46. // A version of AMI_sort that takes an input stream of elements of
  47. // type T, creates an output stream, and a user-specified comparison
  48. // function
  49. // instream is allocated; *outstream is created
  50. // template<class T>
  51. // AMI_err AMI_sort(AMI_STREAM<T> *instream, AMI_STREAM<T> **outstream,
  52. // int (*cmp)(const T&, const T&)) {
  53. // cout << "Not implemented yet!\n";
  54. // exit(1);
  55. // return AMI_ERROR_NO_ERROR;
  56. // }
  57. /* ---------------------------------------------------------------------- */
  58. // A version of AMI_sort that takes an input stream of elements of
  59. // type T, creates an output stream, and a user-specified comparison
  60. // object.
  61. //The comparison object "cmp", of (user-defined) class represented by
  62. //CMPR, must have a member function called "compare" which is used for
  63. //sorting the input stream.
  64. // create *outstream
  65. template<class T, class Compare>
  66. AMI_err
  67. AMI_sort(AMI_STREAM<T> *instream, AMI_STREAM<T> **outstream, Compare *cmp,
  68. int deleteInputStream = 0)
  69. {
  70. char* name=NULL;
  71. queue<char*>* runList;
  72. off_t instreamLength;
  73. assert(instream && outstream && cmp);
  74. instreamLength = instream->stream_len();
  75. if (instreamLength == 0) {
  76. *outstream = new AMI_STREAM<T>();
  77. if (deleteInputStream) {
  78. delete instream;
  79. }
  80. return AMI_ERROR_NO_ERROR;
  81. }
  82. SORT_DEBUG {
  83. instream->name(&name);
  84. cout << "AMI_sort: sorting stream" << name <<", len="
  85. << instreamLength << endl;
  86. delete name;
  87. MM_manager.print();
  88. }
  89. //run formation
  90. runList = runFormation(instream, cmp);
  91. assert(runList);
  92. if (deleteInputStream) {
  93. delete instream;
  94. }
  95. if(runList->length() == 0) {
  96. /* self-check */
  97. fprintf(stderr, "ami_sort: Error - no runs created!\n");
  98. instream->name(&name);
  99. cout << "ami_sort: instream = " << name << endl;
  100. exit(1);
  101. /* no input... */
  102. /* *outstream = new AMI_STREAM<T>(); */
  103. } else if(runList->length() == 1) {
  104. //if 1 run only
  105. runList->dequeue(&name);
  106. //printf("SORT: %s\n", name); fflush(stdout);
  107. *outstream = new AMI_STREAM<T>(name);
  108. delete name; //should be safe, stream makes its own copy
  109. } else {
  110. /* many runs */
  111. *outstream = multiMerge<T,Compare>(runList, cmp);
  112. //i thought the templates are not needed in the call, but seems to
  113. //help the compiler..laura
  114. }
  115. assert(runList->length() == 0);
  116. delete runList;
  117. SORT_DEBUG {
  118. cout << "AMI_sort: done" << endl << endl;
  119. MM_manager.print();
  120. }
  121. assert(*outstream);
  122. assert((*outstream)->stream_len() == instreamLength);
  123. return AMI_ERROR_NO_ERROR;
  124. }
  125. template<class T, class Compare>
  126. int
  127. isSorted(AMI_STREAM<T> *str, Compare cmp) {
  128. T *prev, *crt;
  129. AMI_err ae;
  130. assert(str);
  131. str->seek(0);
  132. if (str->stream_len() <2) return 1;
  133. ae = str->read_item(&crt);
  134. cout << "reading: " << *crt << endl;
  135. prev = new T (*crt);
  136. ae = str->read_item(&crt);
  137. while (ae == AMI_ERROR_NO_ERROR) {
  138. cout << "reading: " << *crt << endl;
  139. if (cmp.compare(*prev, *crt) != -1)
  140. assert(0);
  141. return 0;
  142. prev = crt;
  143. ae = str->read_item(&crt);
  144. }
  145. return 1;
  146. }
  147. #endif // _AMI_SORT_H