#include <Page_Reduced_Reader.hh>
Inheritance diagram for Page_Reduced_Reader:
Public Methods | |
Page_Reduced_Reader (const char *const reference_trace_directory_pathname) | |
The constructor. | |
virtual | ~Page_Reduced_Reader () |
The destructor. | |
virtual void | read (reference_record_s *const reference_record) |
Read the next record from the reference trace. | |
Protected Attributes | |
task_reader_pair_queue_t | task_reader_pair_queue |
A queue that stores and orders task ID/per-task-reader pairs. |
It defines only the read() method that performs the actual reading, parsing, and processing of each reference record before it is provided to the caller in a reference_record_s structure.
Definition at line 81 of file Page_Reduced_Reader.hh.
|
The constructor.
Definition at line 42 of file Page_Reduced_Reader.cc. References BUFFER_SIZE, task_ID_t, and task_reader_pair_t.
00042 { 00043 00044 // Ensure that the inhereted single reference stream is nullified. 00045 reference_stream = NULL; 00046 00047 // Construct the pathnames for the reduction memory size file and 00048 // the task ID list file. 00049 char reduction_memory_size_pathname[BUFFER_SIZE]; 00050 sprintf(reduction_memory_size_pathname, 00051 "%s/%s", 00052 reference_trace_directory_pathname, 00053 REDUCTION_MEMORY_SIZE_FILENAME); 00054 char task_ID_list_pathname[BUFFER_SIZE]; 00055 sprintf(task_ID_list_pathname, 00056 "%s/%s", 00057 reference_trace_directory_pathname, 00058 TASK_ID_LIST_FILENAME); 00059 00060 // Attempt to open these two files, checking that they opened 00061 // successfully. 00062 FILE* const reduction_memory_size_stream = 00063 fopen(reduction_memory_size_pathname, "r"); 00064 if (reduction_memory_size_stream == NULL) { 00065 perror("Failed to open reduction memory size file"); 00066 exit(1); 00067 } 00068 FILE* const task_ID_list_stream = fopen(task_ID_list_pathname, "r"); 00069 if (task_ID_list_stream == NULL) { 00070 perror("Failed to open task ID list file"); 00071 exit(1); 00072 } 00073 00074 // Read the reduction memory size, ensuring success. 00075 unsigned int reduction_memory_size; 00076 int read_result = fscanf(reduction_memory_size_stream, 00077 "%d", 00078 &reduction_memory_size); 00079 if (read_result != 1) { 00080 fprintf(stderr, "Page_Reduced_Reader::Page_Reduced_Reader(): "); 00081 fprintf(stderr, "Failed to read reduction memory size\n"); 00082 exit(1); 00083 } 00084 00085 // Close the reduction memory size file. 00086 int close_result = fclose(reduction_memory_size_stream); 00087 if (close_result == EOF) { 00088 perror("Failed to close reduction memory size file"); 00089 exit(1); 00090 } 00091 00092 // Loop through entries in the task ID list, each time opening the 00093 // corresponding reference trace file and placing an entry in the 00094 // table that maps task IDs to reference trace streams. 00095 bool done = false; 00096 do { 00097 00098 // Attempt to read the next entry in the task ID list. 00099 task_ID_t task_ID; 00100 int read_result = fscanf(task_ID_list_stream, 00101 "%hd\n", 00102 &task_ID); 00103 00104 // Check the result of the read? 00105 if (read_result == 0) { 00106 00107 // Failure to parse. 00108 fprintf(stderr, "Page_Reduced_Reader::Page_Reduced_Reader(): "); 00109 fprintf(stderr, "Failed parse of task ID\n"); 00110 exit(1); 00111 00112 } else if (read_result == EOF) { 00113 00114 // An I/O error. If it's an EOF, that's normal; other kinds of 00115 // errors are not. 00116 if (feof(task_ID_list_stream)) { 00117 done = true; 00118 } else { 00119 fprintf(stderr, "Page_Reduced_Reader::Page_Reduced_Reader(): "); 00120 fprintf(stderr, "Failed read of task ID list file\n"); 00121 exit(1); 00122 } 00123 00124 } else { 00125 00126 // The read succeeded. Create a per-task reader for this task 00127 // ID. 00128 Per_Task_Page_Reduced_Reader* per_task_reader = 00129 new Per_Task_Page_Reduced_Reader(reference_trace_directory_pathname, 00130 reduction_memory_size, 00131 task_ID); 00132 00133 // Add a list entry to associate this task ID with its reader. 00134 task_reader_pair_t* task_reader_pair = 00135 new task_reader_pair_t(task_ID, per_task_reader); 00136 task_reader_pair_queue.push(task_reader_pair); 00137 00138 } 00139 00140 } while (!done); 00141 00142 // Close the task ID list file. 00143 close_result = fclose(task_ID_list_stream); 00144 if (close_result == EOF) { 00145 perror("Failed to close task ID list file"); 00146 exit(1); 00147 } 00148 00149 } // Page_Reduced_Reader |
|
The destructor. Close all input streams and deallocate any dynamically allocated data members. Definition at line 155 of file Page_Reduced_Reader.cc. References task_reader_pair_queue.
00155 { 00156 00157 // Sanity check: It should be the case that all of the reference 00158 // traces have been completed consumed, and thus all per-task 00159 // readers should have been eliminated. 00160 if (!task_reader_pair_queue.empty()) { 00161 fprintf(stderr, "Page_Reduced_Reader::~Page_Reduced_Reader(): "); 00162 fprintf(stderr, "Per-task readers remaining\n"); 00163 exit(1); 00164 } 00165 00166 } // ~Page_Reduced_Reader |
|
Read the next record from the reference trace.
Implements Reference_Reader. Definition at line 174 of file Page_Reduced_Reader.cc. References Per_Task_Page_Reduced_Reader::at_end_of_trace(), Per_Task_Page_Reduced_Reader::get_record(), TAG_END_OF_TRACE, and task_reader_pair_t.
00174 { 00175 00176 // Are there any open traces with records still to read? 00177 if (task_reader_pair_queue.empty()) { 00178 00179 // There are no more records to read from any trace. Return an 00180 // end-of-trace record and a value that indicates that no 00181 // reference records were available. 00182 reference_record->tag = TAG_END_OF_TRACE; 00183 00184 } else { 00185 00186 // There is at least one more record in some task's trace to read. 00187 // Grab the task/reader pair at the top of the queue (and thus the 00188 // one with the smallest timestamp). Remove it from the queue. 00189 task_reader_pair_t* smallest_task_reader_pair = 00190 task_reader_pair_queue.top(); 00191 Per_Task_Page_Reduced_Reader* per_task_reader = 00192 smallest_task_reader_pair->second; 00193 task_reader_pair_queue.pop(); 00194 00195 // Grab the record from this task's reader. 00196 per_task_reader->get_record(reference_record); 00197 00198 // Have we reached the end of this trace? (That is, does the next 00199 // record indicate an end-of-trace for this task?) 00200 if (per_task_reader->at_end_of_trace()) { 00201 00202 // There are no more records in this trace. Delete the per task 00203 // reader and the task/reader pair. 00204 delete per_task_reader; 00205 per_task_reader = 0; 00206 delete smallest_task_reader_pair; 00207 smallest_task_reader_pair = 0; 00208 00209 } else { 00210 00211 // There remain more records in this trace. Re-insert the 00212 // task/reader pair into the priority queue. 00213 task_reader_pair_queue.push(smallest_task_reader_pair); 00214 00215 } 00216 } 00217 00218 } // read |
|
A queue that stores and orders task ID/per-task-reader pairs. A priority queue that holds pairs which associate a task ID with its per-task reference trace reader. The pairs are ordered by the timestamp of the next record, where obtaining the element in the queue is the one with the smallest timestamp. Definition at line 134 of file Page_Reduced_Reader.hh. Referenced by ~Page_Reduced_Reader(). |