Ticket #8094: file_preallocation_v3.patch

File file_preallocation_v3.patch, 6.5 KB (added by Underground78, 5 years ago)
  • src/engine/file.cpp

     
    7979    return ret;
    8080}
    8181
     82bool CFile::Truncate()
     83{
     84    return !!SetEndOfFile(hFile_);
     85}
     86
    8287ssize_t CFile::Read(void *buf, size_t count)
    8388{
    8489    ssize_t ret = -1;
     
    171176    return ret;
    172177}
    173178
     179bool CFile::Truncate()
     180{
     181    bool ret = false;
     182
     183    auto length = lseek(fd_, 0, SEEK_CUR);
     184    if (length != static_cast<off_t>(-1)) {
     185        do {
     186            ret = !ftruncate(fd_, length);
     187        } while (!ret && (errno == EAGAIN || errno == EINTR));
     188    }
     189
     190    return ret;
     191}
     192
    174193ssize_t CFile::Read(void *buf, size_t count)
    175194{
    176195    ssize_t ret;
  • src/engine/file.h

     
    4848    // On failure, the new position in the file is undefined.
    4949    wxFileOffset Seek(wxFileOffset offset, seekMode m);
    5050
     51    // Truncate the file to the current position of the file pointer.
     52    bool Truncate();
     53
    5154    // Returns number of bytes read or -1 on error
    5255    ssize_t Read(void *buf, size_t count);
    5356
  • src/engine/ftpcontrolsocket.cpp

     
    26012601                    pData->resumeOffset = 0;
    26022602
    26032603                InitTransferStatus(pData->remoteFileSize, startOffset, false);
     2604
     2605                if (m_pEngine->GetOptions().GetOptionVal(OPTION_PREALLOCATE_SPACE))
     2606                {
     2607                    // Try to preallocate the file in order to reduce fragmentation
     2608                    wxFileOffset sizeToPreallocate = pData->remoteFileSize - startOffset;
     2609                    if (sizeToPreallocate > 0)
     2610                    {
     2611                        LogMessage(MessageType::Debug_Info, _T("Preallocating %") wxFileOffsetFmtSpec _T("d bytes for the file \"%s\""), sizeToPreallocate, pData->localFile);
     2612                        wxFileOffset oldPos = pFile->Seek(0, CFile::current);
     2613                        if (pFile->Seek(sizeToPreallocate, CFile::end) == pData->remoteFileSize)
     2614                        {
     2615                            if (!pFile->Truncate())
     2616                                LogMessage(MessageType::Debug_Warning, _T("Impossible to preallocate the file"));
     2617                        }
     2618                        pFile->Seek(oldPos, CFile::begin);
     2619                    }
     2620                }
    26042621            }
    26052622            else {
    26062623                if (!pFile->Open(pData->localFile, CFile::read)) {
  • src/engine/iothread.cpp

     
    2929
    3030CIOThread::~CIOThread()
    3131{
    32     delete m_pFile;
     32    if (m_pFile)
     33    {
     34        // The file might have been preallocated and the transfer stopped before being completed
     35        // so always truncate the file to the actually written size before closing it.
     36        if (!m_read)
     37            m_pFile->Truncate();
    3338
     39        delete m_pFile;
     40    }
     41
    3442    for (unsigned int i = 0; i < BUFFERCOUNT; i++)
    3543        delete [] m_buffers[i];
    3644
     
    4048bool CIOThread::Create(CFile* pFile, bool read, bool binary)
    4149{
    4250    wxASSERT(pFile);
    43     delete m_pFile;
     51
     52    if (m_pFile)
     53    {
     54        // The file might have been preallocated and the transfer stopped before being completed
     55        // so always truncate the file to the actually written size before closing it.
     56        if (!m_read)
     57            m_pFile->Truncate();
     58
     59        delete m_pFile;
     60    }
     61
    4462    m_pFile = pFile;
    4563    m_read = read;
    4664    m_binary = binary;
  • src/include/optionsbase.h

     
    4141    OPTION_SPEEDLIMIT_OUTBOUND,
    4242    OPTION_SPEEDLIMIT_BURSTTOLERANCE,
    4343
     44    OPTION_PREALLOCATE_SPACE,
     45
    4446    OPTION_VIEW_HIDDEN_FILES,
    4547
    4648    OPTION_PRESERVE_TIMESTAMPS,
  • src/interface/Options.cpp

     
    7777    { "Speedlimit inbound", number, _T("100"), normal },
    7878    { "Speedlimit outbound", number, _T("20"), normal },
    7979    { "Speedlimit burst tolerance", number, _T("0"), normal },
     80    { "Preallocate space", number, _T("1"), normal },
    8081    { "View hidden files", number, _T("0"), normal },
    8182    { "Preserve timestamps", number, _T("0"), normal },
    8283    { "Socket recv buffer size (v2)", number, _T("4194304"), normal }, // Make it large enough by default
  • src/interface/resources/xrc/settings.xrc

     
    946946                  </content>
    947947                </object>
    948948              </object>
    949               <object class="sizeritem">
    950                 <object class="wxStaticText">
    951                 </object>
    952               </object>
    953949              <cols>2</cols>
    954950              <vgap>5</vgap>
    955951              <hgap>5</hgap>
     
    10071003        </object>
    10081004        <flag>wxGROW</flag>
    10091005      </object>
     1006      <object class="sizeritem">
     1007        <object class="wxStaticBoxSizer">
     1008          <label>Preallocation</label>
     1009          <orient>wxVERTICAL</orient>
     1010          <object class="sizeritem">
     1011            <object class="wxCheckBox" name="ID_ENABLE_PREALLOCATION">
     1012              <label>&amp;Preallocate space before downloading</label>
     1013            </object>
     1014            <flag>wxLEFT|wxRIGHT|wxTOP</flag>
     1015            <border>4</border>
     1016          </object>
     1017        </object>
     1018        <flag>wxGROW</flag>
     1019      </object>
     1020      <object class="sizeritem">
     1021        <object class="wxStaticText">
     1022        </object>
     1023      </object>
    10101024    </object>
    10111025  </object>
    10121026  <object class="wxPanel" name="ID_SETTINGS_FILETYPE">
  • src/interface/settings/optionspage_transfer.cpp

     
    7070#endif
    7171    XRCCTRL(*this, "ID_REPLACED", wxStaticText)->SetLabel(filtered);
    7272
     73    bool enable_preallocation = m_pOptions->GetOptionVal(OPTION_PREALLOCATE_SPACE) != 0;
     74    SetCheck(XRCID("ID_ENABLE_PREALLOCATION"), enable_preallocation, failure);
     75
    7376    return !failure;
    7477}
    7578
     
    8790    SetOptionFromText(XRCID("ID_REPLACE"), OPTION_INVALID_CHAR_REPLACE);
    8891    SetOptionFromCheck(XRCID("ID_ENABLE_REPLACE"), OPTION_INVALID_CHAR_REPLACE_ENABLE);
    8992
     93    SetOptionFromCheck(XRCID("ID_ENABLE_PREALLOCATION"), OPTION_PREALLOCATE_SPACE);
     94
    9095    return true;
    9196}
    9297