2 Copyright (C) 2008 Steve Thomas <SMT837784@yahoo.com>
4 This file is part of RT Perfecter v0.0.
6 RT Perfecter v0.0 is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 RT Perfecter v0.0 is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with RT Perfecter v0.0. If not, see <http://www.gnu.org/licenses/>.
31 // I know Microsoft's compiler, .Net 2005 or older, does not come with this file.
32 // You can use this if you don't have dirent.h: http://www.cs.fiu.edu/~weiss/cop4338_spr06/dirent.h
33 // Umm I'm not sure if the license on that file, which appears to be public domain, conflicts with GPL v3.
34 // So only use that if you need it and the licenses don't conflict.
40 #define DIRECTORY_SEPERATOR '\\'
43 #define DIRECTORY_SEPERATOR '/'
52 RTRead::RTRead(char *dir, uint64 maxIndex, int verbose)
54 int dirLen = strlen(dir), dirFileLen;
55 char *file = new char[dirLen + NAME_MAX + 2];
57 struct dirent *pDirFile;
58 FileList *head = NULL, *current = NULL, *temp = new FileList;
62 m_maxIndex = maxIndex;
68 strncpy(file, dir, dirLen);
69 if (dir[dirLen - 1] != DIRECTORY_SEPERATOR)
71 file[dirLen] = DIRECTORY_SEPERATOR;
79 printf("Error #%u: Opening directory '%s'\n", errno, dir);
84 for (pDirFile = readdir(pDir); pDirFile != NULL; pDirFile = readdir(pDir))
86 dirFileLen = strlen(pDirFile->d_name);
87 if (pDirFile->d_name[0] != '.' && dirFileLen > 3 &&
88 pDirFile->d_name[dirFileLen - 3] == '.' &&
89 (pDirFile->d_name[dirFileLen - 2] == 'r' || pDirFile->d_name[dirFileLen - 2] == 'R') &&
90 (pDirFile->d_name[dirFileLen - 1] == 't' || pDirFile->d_name[dirFileLen - 1] == 'T'))
92 strcpy(file + dirLen, pDirFile->d_name);
93 if (getInfo(file, dirLen + dirFileLen, temp) == 0)
95 m_chains += temp->chains;
104 current->next = temp;
112 printf("Continue? (y/n): ");
114 while (ch != EOF && ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N')
118 if (ch != 'y' && ch != 'Y')
124 fclose(current->pFile);
125 delete [] current->name;
141 printf("Error no '*.rt' input files found in directory '%s'.\n", dir);
145 // Push file list into priority queue
146 PriorityQueueNode tmpNode;
147 unsigned int i = 0, node, par;
149 m_pq = new PriorityQueueNode[m_pqSize];
152 if (readGoodChain(head->pFile, &(m_pq[i].chain)) == 0)
154 // Init priority queue node
155 m_pq[i].pFile = head->pFile;
156 m_pq[i].fName = head->name;
158 // Insert into priority queue
162 par = (node - 1) >> 1;
163 if (m_pq[par].chain.endpt > m_pq[node].chain.endpt)
165 tmpNode = m_pq[node];
168 m_pq[node] = m_pq[par];
174 par = (node - 1) >> 1;
175 } while (m_pq[par].chain.endpt > tmpNode.chain.endpt);
179 m_pq[node] = tmpNode;
187 printf("File had no valid chains '%s'\n", head->name);
188 delete [] head->name;
191 // Delete file list node
197 printf("Starting with %u files.\n", m_pqSize);
198 m_startTime = clock();
205 for (unsigned int i = 0; i < m_pqSize; i++)
207 if (m_pq[i].pFile != NULL)
209 fclose(m_pq[i].pFile);
211 if (m_pq[i].fName != NULL)
213 delete [] m_pq[i].fName;
220 int RTRead::readChain(RTChain *chain)
222 PriorityQueueNode tmp;
223 unsigned int child, node;
229 *chain = m_pq[0].chain;
230 bool remove = (readGoodChain(m_pq[0].pFile, &(m_pq[0].chain)) != 0);
236 printf("Finished with file '%s'\n", m_pq[0].fName);
238 delete [] m_pq[0].fName;
240 // Remove node from queue
244 if (m_pq[1].chain.endpt < m_pq[2].chain.endpt)
253 m_pq[2].fName = NULL;
254 m_pq[2].pFile = NULL;
256 else if (m_pqSize == 1)
259 m_pq[1].fName = NULL;
260 m_pq[1].pFile = NULL;
262 else if (m_pqSize == 0)
272 tmp = m_pq[m_pqSize];
273 m_pq[m_pqSize].fName = NULL;
274 m_pq[m_pqSize].pFile = NULL;
280 // Move tmp node to proper posistion in queue
283 if (m_pq[1].chain.endpt > m_pq[2].chain.endpt)
287 while (tmp.chain.endpt > m_pq[child].chain.endpt)
289 m_pq[node] = m_pq[child];
292 child = (node << 1) + 1;
293 if (child >= m_pqSize)
297 if (child + 1 < m_pqSize && m_pq[child].chain.endpt > m_pq[child + 1].chain.endpt)
299 // child = right node
303 if (node != 0 || remove)
308 else if (m_pqSize == 2 && !remove)
310 if (m_pq[0].chain.endpt > m_pq[1].chain.endpt)
320 int RTRead::readGoodChain(FILE *pFile, RTChain *chain)
330 ret = fread((void*)chain, 16, 1, pFile);
331 if(ret == 1) ret = fread((void*)&chain->checkpoint, 2, 1, pFile);
334 if (ferror(pFile) != 0)
336 printf("Error reading file.\n");
337 printf("Continue? (y/n): ");
339 while (ch != EOF && ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N')
343 if (ch != 'y' && ch != 'Y')
349 else if (feof(pFile) != 0)
359 } while (ret != 1 || chain->startpt > m_maxIndex || chain->endpt > m_maxIndex);
363 void RTRead::printStatus()
365 double percent = ((double) m_chainsRead / (double) m_chains) * 100.0;
366 double timeElapsed = (clock() - m_startTime) / (double)CLOCKS_PER_SEC;
368 printf("\n*** Status ***\n");
370 printf(" Chains Read: %I64u\n", m_chainsRead);
371 printf(" Total Chains: %I64u\n", m_chains);
373 printf(" Chains Read: %llu\n", m_chainsRead);
374 printf(" Total Chains: %llu\n", m_chains);
376 printf(" Files Open: %u\n", m_pqSize);
377 printf(" Percent: %0.1f\n", percent);
378 printf(" Time Elapsed: %0.0f sec\n", timeElapsed);
379 printf(" Time Left: %0.0f sec\n\n", timeElapsed / (percent / 100.0) - timeElapsed);
382 int RTRead::getInfo(char *file, int len, FileList *ret)
389 printf("Opening file '%s'\n", file);
391 pFile = fopen(file, "rb");
399 fseek(pFile, 0, SEEK_END);
404 printf("Error file size of '%s' is not a multible of 16 bytes.\n", file);
407 fseek(pFile, 0, SEEK_SET);
408 ret->chains = size >> 4;
411 ret->name = new char[len + 1];
412 strncpy(ret->name, file, len);
413 ret->name[len] = '\0';