Aleks11

External Sort(with BigEndian)

May 17th, 2013
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.10 KB | None | 0 0
  1. #include <conio.h>
  2. #include <stdio.h>
  3. #include <queue>
  4. #include <stack>
  5. #include <time.h>
  6. #include <vector>
  7. #include <Windows.h>
  8.  
  9. using namespace std;
  10.  
  11. // task 2
  12.  
  13. #define TEMP_FILE_NAME      "TempFiles\\task2temp.txt"
  14. #define MAX_TEMP_FILES      8
  15. #define MAX_ELEMS_IN_MEM    262
  16. #define AMOUNT_OF_NUMBERS   200000
  17.  
  18. class HRTimer
  19. {
  20. public:
  21.     HRTimer() : frequency(GetFrequency()) { }
  22.     LONGLONG GetFrequency()
  23.     {
  24.         LARGE_INTEGER proc_freq;
  25.         QueryPerformanceFrequency(&proc_freq);
  26.         return proc_freq.QuadPart;
  27.     }
  28.     void Reset()
  29.     {
  30.         DWORD_PTR oldmask = SetThreadAffinityMask(GetCurrentThread(), 0);
  31.         QueryPerformanceCounter(&start);
  32.         SetThreadAffinityMask(GetCurrentThread(), oldmask);
  33.     }
  34.     double GetElapsed()
  35.     {
  36.         DWORD_PTR oldmask = SetThreadAffinityMask(GetCurrentThread(), 0);
  37.         QueryPerformanceCounter(&stop);
  38.         SetThreadAffinityMask(GetCurrentThread(), oldmask);
  39.         return ((stop.QuadPart - start.QuadPart) / (double)frequency);
  40.     }
  41. private:
  42.     LARGE_INTEGER start;
  43.     LARGE_INTEGER stop;
  44.     LONGLONG frequency;
  45. };
  46. HRTimer timer;
  47.  
  48. int LogicalRightShift(int _nNumber, int _nShiftStep)
  49. {
  50.     return (_nNumber >> _nShiftStep) & ~(0xFFFFFFFF << (32 - _nShiftStep));
  51.     //return (int)((unsigned int)_nNumber >> _nShiftStep);
  52. }
  53.  
  54. int ConvToBigLittleEnd(int _nNumber)
  55. {
  56.     return
  57.         ((_nNumber & 0xFF) << 24) |
  58.         ((LogicalRightShift(_nNumber, 8) & 0xFF) << 16) |
  59.         ((LogicalRightShift(_nNumber, 16) & 0xFF) << 8) |
  60.         LogicalRightShift(_nNumber, 24);
  61. }
  62.  
  63. void fwriteBigEndian(FILE *_pFile, int _nNumber)
  64. {
  65.     int nNumber = ConvToBigLittleEnd(_nNumber);
  66.     fwrite(&nNumber, 4, 1, _pFile);
  67. }
  68.  
  69. int freadBigEndian(FILE *_pFile)
  70. {
  71.     int nNumber;
  72.     fread_s(&nNumber, 4, 4, 1, _pFile);
  73.  
  74.     nNumber = ConvToBigLittleEnd(nNumber);
  75.  
  76.     return nNumber;
  77. }
  78.  
  79. /*
  80.  
  81.     Функция создаёт файл примера с рандомными числами в формате BigEndian
  82.  
  83. */
  84. void ContructExample()
  85. {
  86.     srand((unsigned int)time(NULL));
  87.  
  88.     FILE *pFile;
  89.     fopen_s(&pFile, "task2.txt", "wb");
  90.  
  91.     for (int i = 0; i < AMOUNT_OF_NUMBERS; i++)
  92.     {
  93.         int nNumber = rand() - rand();
  94.         fwriteBigEndian(pFile, nNumber);
  95.  
  96.         //printf("%d ", nNumber);
  97.     }
  98.  
  99.     //printf("\n\n");
  100.  
  101.     fclose(pFile);
  102. }
  103.  
  104. /*
  105.  
  106.     Функция разбивает файл с числами на несколько файлов, в которых числа отсортированы по возрастанию
  107.  
  108. */
  109. void FirstStep()
  110. {
  111.     FILE *pTempFiles[MAX_TEMP_FILES];
  112.     FILE *pSourceFile;
  113.     FILE *pTempFile;
  114.  
  115.     int *pTempArray = new int[MAX_ELEMS_IN_MEM];
  116.  
  117.     fopen_s(&pSourceFile, "task2.txt", "rb");
  118.     if (!pSourceFile)
  119.         return;
  120.  
  121.     fopen_s(&pTempFile, TEMP_FILE_NAME, "wb");
  122.     if (!pTempFile)
  123.         return;
  124.  
  125.     char sName[40];
  126.     for (int i = 0; i < MAX_TEMP_FILES; i++)
  127.     {
  128.         sprintf_s(sName, 40, "TempFiles\\test%d.txt", i);
  129.         fopen_s(&pTempFiles[i], sName, "wb");
  130.         if (!pTempFiles[i])
  131.             return;
  132.  
  133.         fclose(pTempFiles[i]);
  134.  
  135.         fopen_s(&pTempFiles[i], sName, "rb");
  136.     }
  137.  
  138.     int nIDTempFile = 0;
  139.  
  140.     while (!feof(pSourceFile))
  141.     {
  142.         int nNumReadedNumbs = 0;
  143.         int nTmp = 0;
  144.  
  145.         for (int i = 0; i < MAX_ELEMS_IN_MEM; i++)
  146.         {
  147.             if (!fread_s(&pTempArray[i], 4, 4, 1, pSourceFile))
  148.                 break;
  149.  
  150.             pTempArray[i] = ConvToBigLittleEnd(pTempArray[i]);
  151.  
  152.             nNumReadedNumbs++;
  153.         }
  154.  
  155.         sort(pTempArray, pTempArray + nNumReadedNumbs);
  156.  
  157.         bool bWaitingWriting = false;
  158.         for (int i = 0; i < nNumReadedNumbs; i++)
  159.         {
  160.             while (1)
  161.             {
  162.                 if (!bWaitingWriting)
  163.                 {
  164.                     bWaitingWriting = fread_s(&nTmp, 4, 4, 1, pTempFiles[nIDTempFile]) != 0;
  165.                 }
  166.  
  167.                 if (!bWaitingWriting || nTmp > pTempArray[i])
  168.                     break;
  169.  
  170.                 fwrite(&nTmp, 4, 1, pTempFile);
  171.                 bWaitingWriting = false;
  172.             }
  173.  
  174.             fwrite(&pTempArray[i], 4, 1, pTempFile);
  175.         }
  176.  
  177.         if (bWaitingWriting)
  178.         {
  179.             fwrite(&nTmp, 4, 1, pTempFile);
  180.         }
  181.  
  182.         while (fread_s(&nTmp, 4, 4, 1, pTempFiles[nIDTempFile]))
  183.         {
  184.             fwrite(&nTmp, 4, 1, pTempFile);
  185.         }
  186.        
  187.         fclose(pTempFiles[nIDTempFile]);
  188.         fclose(pTempFile);
  189.  
  190.         sprintf_s(sName, 40, "TempFiles\\test%d.txt", nIDTempFile);
  191.         remove(sName);
  192.         rename(TEMP_FILE_NAME, sName);
  193.  
  194.         fopen_s(&pTempFile, TEMP_FILE_NAME, "wb");
  195.         fopen_s(&pTempFiles[nIDTempFile], sName, "rb");
  196.         if (!pTempFiles[nIDTempFile])
  197.             return;
  198.  
  199.         nIDTempFile = (nIDTempFile + 1) % MAX_TEMP_FILES;
  200.     }
  201.  
  202.     fclose(pSourceFile);
  203.     fclose(pTempFile);
  204.    
  205.     for (int i = 0; i < MAX_TEMP_FILES; i++)
  206.     {
  207.         fclose(pTempFiles[i]);
  208.     }
  209.  
  210.     delete[] pTempArray;
  211. }
  212.  
  213. /*
  214.  
  215.     Функция собирает временные файлы в один(похожа техника на merge sort).
  216.  
  217. */
  218. void SecondStep()
  219. {
  220.     class CData
  221.     {
  222.     public:
  223.         CData()
  224.         {
  225.             pFile = nullptr;
  226.         }
  227.         ~CData()
  228.         {
  229.             if (pFile)
  230.             {
  231.                 fclose(pFile);
  232.                 pFile = nullptr;
  233.             }
  234.         }
  235.  
  236.         int nCurElem;
  237.         FILE *pFile;
  238.     };
  239.     vector<CData> Files(MAX_TEMP_FILES);
  240.  
  241.     FILE *pSourceFile;
  242.     fopen_s(&pSourceFile, "task2Result.txt", "wb");
  243.     if (!pSourceFile)
  244.         return;
  245.  
  246.     char sName[40];
  247.  
  248.     stack<vector<CData>::iterator> StackToErase;
  249.     for (int i = 0; i < MAX_TEMP_FILES; i++)
  250.     {
  251.         sprintf_s(sName, 40, "TempFiles\\test%d.txt", i);
  252.         fopen_s(&Files[i].pFile, sName, "rb");
  253.         if (!Files[i].pFile)
  254.             return;
  255.  
  256.         if (!fread_s(&Files[i].nCurElem, 4, 4, 1, Files[i].pFile))
  257.             StackToErase.push(Files.begin() + i);
  258.     }
  259.  
  260.     while (!StackToErase.empty())
  261.     {
  262.         Files.erase(StackToErase.top());
  263.         StackToErase.pop();
  264.     }
  265.  
  266.     while (!Files.empty())
  267.     {
  268.         int nMinimum = Files.begin()->nCurElem;
  269.         auto FileWithMinimum = Files.begin();
  270.  
  271.         for (auto it = Files.begin(); it != Files.end(); it++)
  272.         {
  273.             if (nMinimum > it->nCurElem)
  274.             {
  275.                 nMinimum = it->nCurElem;
  276.                 FileWithMinimum = it;
  277.             }
  278.         }
  279.  
  280.         if (!fread_s(&FileWithMinimum->nCurElem, 4, 4, 1, FileWithMinimum->pFile))
  281.             Files.erase(FileWithMinimum);
  282.  
  283.         //printf("%d ", nMinimum);
  284.         fwriteBigEndian(pSourceFile, nMinimum);
  285.     }
  286.  
  287.     //printf("\n");
  288.  
  289.     fclose(pSourceFile);
  290. }
  291.  
  292. int main()
  293. {
  294.     _wmkdir(L"TempFiles");
  295.  
  296.     timer.Reset();
  297.  
  298.     ContructExample();
  299.  
  300.     FirstStep();
  301.  
  302.     SecondStep();
  303.  
  304.     printf("The task has done!\n");
  305.     printf("Time: %0.5f\n", timer.GetElapsed());
  306.  
  307.     _getch();
  308.     return 0;
  309. }
Advertisement
Add Comment
Please, Sign In to add comment