Ticket #8094: file_preallocation_v2.patch

File file_preallocation_v2.patch, 3.3 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                // Try to preallocate the file in order to reduce fragmentation
     2606                wxFileOffset sizeToPreallocate = pData->remoteFileSize - startOffset;
     2607                if (sizeToPreallocate > 0)
     2608                {
     2609                    LogMessage(MessageType::Debug_Info, _T("Preallocating %") wxFileOffsetFmtSpec _T("d bytes for the file \"%s\""), sizeToPreallocate, pData->localFile);
     2610                    wxFileOffset oldPos = pFile->Seek(0, CFile::current);
     2611                    if (pFile->Seek(sizeToPreallocate, CFile::end) == pData->remoteFileSize)
     2612                    {
     2613                        if (!pFile->Truncate())
     2614                            LogMessage(MessageType::Debug_Warning, _T("Impossible to preallocate the file"));
     2615                    }
     2616                    pFile->Seek(oldPos, CFile::begin);
     2617                }
    26042618            }
    26052619            else {
    26062620                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;