StorageWrapper.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:45k
源码类别:
P2P编程
开发平台:
Visual C++
- // StorageWrapperEx.cpp: implementation of the CStorageWrapperEx class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "testbt.h"
- #include "StorageWrapper.h"
- #include "storage.h"
- #include "Downloader.h"
- #include "DownloaderFeedback.h"
- #include "Sha.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CStorageWrapper::CStorageWrapper(const vector<CSize>& vUnNeededFileInxs)
- {
- //
- // set file inxs. make it at the end of the function.
- // set it at the first, because it may be called while stroage is checking or allocating.
- //
- SetUnNeededFilesInxs(vUnNeededFileInxs);
- }
- CStorageWrapperEx::CStorageWrapperEx()
- {
- m_pMain = 0;
- m_hevDone = 0;
- m_hevUnPause = 0;
- m_pStorage = 0;
- m_pDownloader = 0;
- m_request_size = 0;
- m_piece_length = 0;
- m_lTotalLength = 0;
- m_lAmountLeft = 0;
- m_lAmountInactive = 0;
- m_bCheckHashes = true;
- m_eAllocType = m_eAllocType;
- m_bDoubleCheck = false;
- m_bTripleCheck = false;
- m_bBgallocEnabled = false;
- m_bBgallocActive = false;
- m_lStatNumflunked = 0;
- m_lStatMumdownloaded = 0;
- m_lStatNumfound = 0;
- time(&m_tLast);
- m_tTimeSpan = 1;
- m_vNone.push_back(size(-1, -1));
- //
- // switch Unneedfiles.
- m_bModified = false;
- m_lPartAmountLeft = 0;
- m_lPartTotalLength = 0;
- m_lPartAmountInactive = 0;
- }
- CStorageWrapperEx::~CStorageWrapperEx()
- {
- }
- bool CStorageWrapperEx::do_I_have(long index)
- {
- // if (IsUnNeededIndex(index))
- // return false;
- assert(index < m_vHave.size());
- return m_vHave[index];
- }
- vector<bool>& CStorageWrapperEx::get_have_list()
- {
- return m_vHave;
- }
- BLONG CStorageWrapperEx::get_total_legth()
- {
- return m_pStorage->GetTotalLength();
- }
- BLONG CStorageWrapperEx::get_amount_left()
- {
- return m_lAmountLeft;
- }
- bool CStorageWrapperEx::do_I_have_anything()
- {
- return m_lAmountLeft < m_lTotalLength;
- }
- bool CStorageWrapperEx::is_everything_pending()
- {
- assert(m_lPartAmountInactive >= 0);
- if (m_lPartAmountInactive <= 0)
- {
- return true;
- }
- return false;
- return m_lAmountInactive == 0;
- }
- bool CStorageWrapperEx::do_I_have_requests(long index)
- {
- assert (index < m_vInactiveRequests.size());
- // if (m_vNone == m_vInactiveRequests[index])
- // return true;
- if (IsUnNeededIndex(index))
- return false;
- return m_vInactiveRequests[index].size() != 0;
- }
- bool CStorageWrapperEx::_do_I_have_requests(long index)
- {
- assert (index < m_vInactiveRequests.size());
- return m_vInactiveRequests[index].size() != 0;
- }
- void CStorageWrapperEx::new_request(long index, long& begin, long& length)
- {
- if (index < 0 || index >= m_vHave.size() || m_vHave[index] || !do_I_have_requests(index))
- {
- assert(false);
- return;
- }
- if (m_vNone == m_vInactiveRequests[index])
- _make_inactive(index);
- m_vNumActive[index]++;
- vector<size> & rs = m_vInactiveRequests[index];
- size r = *rs.begin();
- begin = r.x;
- length = r.y;
- rs.erase(rs.begin());
- m_lAmountInactive -= length;
- m_lPartAmountInactive --; //= length;
- assert(m_lPartAmountInactive >= 0);
- m_pMain->PutFractionsState(index, 2);
- // m_vStatActive[index] = true;
- }
- void CStorageWrapperEx::request_lost(long index, long begin, long length)
- {
- assert(index < m_vInactiveRequests.size() && index >= 0);
- m_vInactiveRequests[index].push_back(size(begin, length));
- m_vNumActive[index]--;
- assert(m_vNumActive[index] >= 0);
- m_lAmountInactive += length;
- m_lPartAmountInactive ++; // = length;
- assert(m_lPartAmountInactive >= 0);
- if (m_vNumActive[index] <= 0)
- m_pMain->PutFractionsState(index, 0);
- }
- void CStorageWrapperEx::_make_inactive(long index)
- {
- assert (index < m_vInactiveRequests.size() && m_request_size > 0 && index >= 0);
- assert(m_vInactiveRequests[index] == m_vNone);
- // long lLength = min(m_piece_length , m_lTotalLength - (BLONG)m_piece_length * index);
- // ASSERT(lLength >= 0 && lLength <= m_piece_length);
- long lLength = _piecelen(index);
- vector<size>& v = m_vInactiveRequests[index];
- v.clear();
- long x = 0;
- while ((x + m_request_size) < lLength)
- {
- v.push_back(size(x, m_request_size));
- x += m_request_size;
- }
- v.push_back(size(x, lLength-x));
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // switch Unneedfiles.
- //
- bool CStorageWrapperEx::_ReadIndexData(char *pBuf, const BLONG lPos, const BLONG lAmount, bool bFlushFirst)
- {
- if (!m_piece_length)
- {
- assert(false);
- return false;
- }
- long index = lPos / m_piece_length;
- ASSERT(index >= 0);
- bool bEdge = false;
- for (int i=0; i<m_vRangeHoles.size(); i++)
- {
- if (index < m_vRangeHoles[i])
- break;
- if (index == m_vRangeHoles[i])
- {
- bEdge = (i > 0);
- break;
- }
- }
- if (bEdge)
- {
- assert(i < m_vFileOffset.size());
- long lfileoffset = m_vFileOffset[i];
- long lPrePartIndex = m_vOffsetTrueIndex[i];
- if (lfileoffset == 0 || lPrePartIndex < 0)
- {
- if (!m_pStorage->read(pBuf, lPos, lAmount, bFlushFirst))
- return false;
- }
- else
- {
- long lbeg = lPos % m_piece_length;
- assert(lbeg >= 0);
- if (lbeg < lfileoffset)
- {
- long len = lfileoffset - lbeg;
- assert(len >= 0);
- if (len >= lAmount)
- {
- if (!m_pStorage->read(pBuf, (BLONG)lPrePartIndex * m_piece_length + lbeg, lAmount, bFlushFirst))
- return false;
- }
- else
- {
- if (!m_pStorage->read(pBuf, (BLONG)lPrePartIndex * m_piece_length + lbeg, len, bFlushFirst))
- return false;
- if (!m_pStorage->read(pBuf + len, (BLONG)index * m_piece_length + lfileoffset, lAmount - len, bFlushFirst))
- return false;
- }
- }
- else
- {
- if (!m_pStorage->read(pBuf, lPos, lAmount, bFlushFirst))
- return false;
- }
- }
- }
- else
- {
- if (!m_pStorage->read(pBuf, lPos, lAmount, bFlushFirst))
- return false;
- }
- return true;
- }
- bool CStorageWrapperEx::_WriteIndexData(char *pBuf, const BLONG lPos, const BLONG lAmount)
- {
- if (!m_piece_length)
- {
- assert(false);
- return false;
- }
- long index = lPos / m_piece_length;
- ASSERT(index >= 0);
- bool bEdge = false;
- for (int i=0; i<m_vRangeHoles.size(); i++)
- {
- if (index < m_vRangeHoles[i])
- break;
- if (index == m_vRangeHoles[i])
- {
- bEdge = (i > 0);
- break;
- }
- }
- if (bEdge)
- {
- assert(i < m_vFileOffset.size());
- long lfileoffset = m_vFileOffset[i];
- long lPrePartIndex = m_vOffsetTrueIndex[i];
- if (lfileoffset == 0 || lPrePartIndex < 0)
- {
- if (!m_pStorage->write(pBuf, lPos, lAmount))
- return false;
- }
- else
- {
- long lbeg = lPos % m_piece_length;
- assert(lbeg >= 0);
- if (lbeg < lfileoffset)
- {
- long len = lfileoffset - lbeg;
- assert(len >= 0);
- if (len >= lAmount)
- {
- if (!m_pStorage->write(pBuf, (BLONG)lPrePartIndex * m_piece_length + lbeg, lAmount))
- return false;
- }
- else
- {
- if (!m_pStorage->write(pBuf, (BLONG)lPrePartIndex * m_piece_length + lbeg, len))
- return false;
- if (!m_pStorage->write(pBuf + len, (BLONG)index * m_piece_length + lfileoffset, lAmount - len))
- return false;
- }
- }
- else
- {
- if (!m_pStorage->write(pBuf, lPos, lAmount))
- return false;
- }
- }
- }
- else
- {
- if (!m_pStorage->write(pBuf, lPos, lAmount))
- return false;
- }
- return true;
- }
- void CStorageWrapperEx::_FormatRangeHoles()
- {
- if (m_piece_length <= 0)
- {
- assert(false);
- return;
- }
- m_pStorage->GetFilesRange(m_vRangeHoles, m_vFileOffset, m_piece_length);
- for (int i=0;i<m_vRangeHoles.size(); i++)
- {
- m_vOffsetTrueIndex.push_back(-1);
- m_vFileOffsetPreAllocated.push_back(false);
- }
- int iRangeHolesSize = m_vRangeHoles.size();
- int iFileOffsetSize = m_vFileOffset.size();
- int iOffsetTrueIndexSize = m_vOffsetTrueIndex.size();
- assert(iRangeHolesSize == iFileOffsetSize);
- assert(iFileOffsetSize == iOffsetTrueIndexSize);
- }
- float CStorageWrapperEx::GetPartCompletedPercent()
- {
- if (m_lPartTotalLength <= 0)
- return 1;
- return (float)(m_lPartTotalLength - m_lPartAmountLeft) / m_lPartTotalLength;
- }
- BLONG CStorageWrapperEx::get_total_legth_part()
- {
- return m_lPartTotalLength;
- }
- BLONG CStorageWrapperEx::get_amount_left_part()
- {
- return m_lPartAmountLeft;
- }
- BLONG CStorageWrapperEx::get_amount_left_part_include_temp()
- {
- BLONG lLeft = m_lPartAmountLeft;
- #ifdef _DEBUG
- int iCount = 0;
- unsigned long lsize = m_mPartAmountIncome.size();
- #endif
- for (map<unsigned long, unsigned long>::iterator i=m_mPartAmountIncome.begin(); i!=m_mPartAmountIncome.end(); i++)
- {
- if (!IsUnNeededIndex((*i).first))
- {
- lLeft += (*i).second;
- }
- #ifdef _DEBUG
- iCount ++;
- #endif
- }
- return lLeft;
- }
- bool CStorageWrapperEx::IsUnNeededIndex(long lIndex)
- {
- assert(lIndex >= 0);
- for (int i=0; i<m_vUnNeededIndexs.size(); i++)
- {
- long cx = m_vUnNeededIndexs[i].cx;
- long cy = m_vUnNeededIndexs[i].cy;
- if (lIndex > cy)
- continue;
- if (lIndex >= cx)
- return true;
- return false;
- }
- return false;
- }
- void CStorageWrapperEx::SetUnNeededFilesInxs(const vector<CSize>& vUnNeededFileInxs)
- {
- CSingleLock singleLock(&m_criticalSection, true);
- m_vUnNeededFileInxs = vUnNeededFileInxs;
- m_bModified = true;
- }
- bool CStorageWrapperEx::_GetUnNeededFilesInxs(vector<CSize>& vUnNeededFileInxs)
- {
- CSingleLock singleLock(&m_criticalSection, true);
- if (!m_bModified) return false;
- vUnNeededFileInxs = m_vUnNeededFileInxs;
- m_bModified = false;
- return true;
- }
- long CStorageWrapperEx::_GetRequestSize(long index)
- {
- assert(index <m_vHave.size() && index >= 0 && m_request_size > 0);
- if (m_request_size <= 0)
- {
- assert(false);
- return -1;
- }
- // long lRequestLength = min(m_piece_length , m_lTotalLength - m_piece_length * index);
- long lRequestLength = _piecelen(index);
- long lRequestCount = lRequestLength / m_request_size + ((lRequestLength % m_request_size) ? 1 : 0);
- assert(lRequestCount > 0 && lRequestLength >= 0);
- return lRequestCount;
- }
- /*************************************************************************************
- lbeg and lend is the true value of file seeking pos,
- which return value is the index value.
- *************************************************************************************/
- bool CStorageWrapperEx::_NormalizeUneedRange(BLONG & lbegPos, BLONG & lendPos)
- {
- assert(lendPos >= 0 && lbegPos >= 0);
- assert(!m_vRangeHoles.empty());
- const long lbegold = lbegPos/m_piece_length, lendold = lendPos/m_piece_length;
- assert(lbegold >= 0 && lendold >= 0);
- if (lbegold > lendold)
- {
- assert(false);
- return false;
- }
- bool bfindbeg = false, bfindend = false;
- for (int i=0; i<m_vRangeHoles.size();i++)
- {
- int iHoleIndex = m_vRangeHoles[i];
- if (lbegold <= m_vRangeHoles[i] && !bfindbeg)
- {
- lbegPos = m_vRangeHoles[i];
- if (m_vFileOffset[i] != 0)
- lbegPos += 1;
- bfindbeg = true;
- }
- // long lsize = m_vRangeHoles.size();
- long x = m_vRangeHoles[i];
- ASSERT(x >= 0);
- if (lendold < m_vRangeHoles[i] && !bfindend)
- {
- assert(bfindbeg);
- assert(i > 0);
- lendPos = m_vRangeHoles[i - 1];
- if (m_vFileOffset[i - 1] != 0)
- lendPos -= 1;
- bfindend = true;
- }
- if (bfindbeg && bfindend)
- break;
- }
- /*
- if (!bfindbeg)
- {
- lbeg = m_vRangeHoles[m_vRangeHoles.size() - 1];
- if (m_vFileOffset[m_vRangeHoles.size() - 1])
- {
- lbeg ++;
- }
- }
- //*/
- if (!bfindend)
- {
- if (lendPos >= m_lTotalLength)
- {
- lendPos = m_lTotalLength / m_piece_length;
- }
- /*
- else if (lendold >= (m_lTotalLength / m_piece_length) )
- {
- lend = m_lTotalLength / m_piece_length;
- if (m_lTotalLength % m_piece_length)
- {
- lend -= 1;
- }
- }
- //*/
- else
- {
- lendPos = m_vRangeHoles[m_vRangeHoles.size() - 1];
- if (m_vFileOffset[m_vRangeHoles.size() - 1] != 0)
- lendPos -= 1;
- }
- bfindend = true;
- }
- // assert(lend >= lbeg);
- return bfindbeg && bfindend && (lendPos >= lendPos);
- }
- void CStorageWrapperEx::_MakeUnNeededIndexs()
- {
- vector<CSize> vUnFileInxs;
- if (!_GetUnNeededFilesInxs(vUnFileInxs))
- return;
- if (!m_piece_length)
- {
- assert(false);
- return;
- }
- m_lPartTotalLength = m_lTotalLength;
- m_lPartAmountLeft = m_lAmountLeft;
- m_vUnNeededIndexs.clear();
- //
- // Get unNeeded files range.
- //
- vector<CSizeEx> vRanges;
- m_pStorage->GetUnNeededRanges(vUnFileInxs, vRanges);
- #ifdef _DEBUG
- TRACE("rn_MakeUnNeededIndexs(%d) : rn", m_vHave.size());
- for (int j=0; j<vRanges.size(); j++)
- {
- TRACE("(%d, %d)", vRanges[j].cx, vRanges[j].cy);
- }
- TRACE("rn*");
- #endif
- //
- // compute the unNeeded indexs.
- //
- for (int i=0; i<vRanges.size(); i++)
- {
- BLONG tx = vRanges[i].cx, ty = vRanges[i].cy;
- /*
- unsigned long cx = vRanges[i].cx/m_piece_length;
- unsigned long cy = vRanges[i].cy/m_piece_length ;
- if (vRanges[i].cx % m_piece_length)
- cx += 1;
- if (vRanges[i].cy % m_piece_length)
- cy -= 1;
- if (vRanges[i].cy >= m_lTotalLength)
- {
- if (vRanges[i].cy%m_piece_length)
- {
- cy ++;
- }
- }
- if (cy >= 0)
- assert(cy < m_vHave.size());
- //*/
- if (!_NormalizeUneedRange(tx, ty))
- continue;
- if (tx >= ty) continue;
- m_vUnNeededIndexs.push_back(CSize(tx, ty));
- }
- //
- // Compute the Needed indexs and amount which had been haved.
- //
- m_lPartAmountInactive = 0;
- m_lPartTotalLength = 0;
- BLONG lAmountHave = 0;
- BLONG lbeg = 0, lend = 0;
- bool bIncludeLastPiece = false;
- int iLastIndex = m_vHave.size() - 1;
- for (i=0; i<m_vUnNeededIndexs.size(); i++)
- {
- CSize range = m_vUnNeededIndexs[i];
- lend = range.cx;
- m_lPartTotalLength += (BLONG)(lend - lbeg) * m_piece_length;
- for (int j=lbeg; j<lend; j++)
- {
- //
- // compute have amount.
- //
- if (j >= m_vHave.size())
- {
- assert(false);
- break;
- }
- if (m_vHave[j])
- lAmountHave += _piecelen(j);
- //
- // compute inactive requests amount.
- //
- if (m_vInactiveRequests[j] == m_vNone)
- {
- long lRequestCount = _GetRequestSize(j);
- assert(lRequestCount >= 0);
- m_lPartAmountInactive += lRequestCount;
- }
- else
- {
- m_lPartAmountInactive += m_vInactiveRequests[j].size();
- }
- }
- lbeg = range.cy + 1;
- }
- if (lbeg <= iLastIndex)
- {
- m_lPartTotalLength += (BLONG)(iLastIndex - lbeg) * m_piece_length;
- m_lPartTotalLength += _piecelen(iLastIndex);
- for (int j=lbeg; j<=iLastIndex; j++)
- {
- //
- // compute have amount.
- //
- if (m_vHave[j])
- lAmountHave += _piecelen(j);
- //
- // compute inactive requests amount.
- //
- if (m_vInactiveRequests[j] == m_vNone)
- {
- long lRequestCount = _GetRequestSize(j);
- m_lPartAmountInactive += lRequestCount;
- }
- else
- {
- m_lPartAmountInactive += m_vInactiveRequests[j].size();
- }
- }
- }
- m_lPartAmountLeft = m_lPartTotalLength - lAmountHave;
- assert(m_lPartAmountLeft >= 0);
- if (m_pDownloader && m_pDownloader->IsCreate())
- {
- if (m_pDownloader->is_endgame()) // && (m_lPartAmountInactive > 0) )
- {
- m_pDownloader->cancel_endgame();
- }
- m_pDownloader->OnNeedFilesChanged();
- }
- #ifdef _DEBUG
- TRACE("rn_MakeUnNeededIndexs(%d) : rn", m_vHave.size());
- for (i=0; i<vUnFileInxs.size();i++)
- {
- TRACE("(%d, %d)", vUnFileInxs[i].cx, vUnFileInxs[i].cy);
- }
- TRACE("rn*");
- TRACE("rn_MakeUnNeededIndexs(%d) : rn", m_vHave.size());
- for (i=0; i<vRanges.size();i++)
- {
- TRACE("(%d, %d)", vRanges[i].cx, vRanges[i].cy);
- }
- TRACE("rn*");
- for (i=0; i<m_vUnNeededIndexs.size();i++)
- {
- TRACE("(%d, %d)", m_vUnNeededIndexs[i].cx, m_vUnNeededIndexs[i].cy);
- }
- TRACE("rn");
- #endif
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //
- bool CStorageWrapperEx::get_piece(long index, char* pPieceBuf, long begin, long length)
- {
- try
- {
- return _get_piece(index, pPieceBuf, begin, length);
- }
- catch (string& e)
- {
- throw string(e);
- }
- }
- bool CStorageWrapperEx::_get_piece(long index, char* pPieceBuf, long begin, long length)
- {
- if (index >= m_vHave.size() || !m_vHave[index] || begin < 0)
- {
- // assert(false);
- return false;
- }
- if ((begin + length) > _piecelen(index))
- {
- assert(false);
- return false;
- }
- // If piece was not checked, check it.
- if (!m_vWasChecked[index])
- {
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- assert(m_mPlaces.find(index) != m_mPlaces.end());
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * m_mPlaces[index], _piecelen(index)))
- return false;
- unsigned char shasum[20] = {0};
- CSHA sha;
- sha.start();
- sha.update((unsigned char*)pszBuf, _piecelen(index));
- sha.finish(shasum);
- if (m_vHashs[index] != shasum)
- {
- // todo : self.failed('told file complete on start-up, but piece failed hash check')
- m_pMain->SetBadMsg("文件已被修改或移动,导致数据丢失,请重新下载"); // told file complete on start-up, but piece failed hash check");
- return false;
- }
- m_vWasChecked[index] = true;
- }
- assert(m_mPlaces.find(index) != m_mPlaces.end());
- if (!_ReadIndexData(pPieceBuf, (BLONG)m_piece_length * m_mPlaces[index] + begin, length))
- return false;
- return true;
- }
- void CStorageWrapperEx::piece_came_in(long index, char *pPieceBuf, long begin, long length)
- {
- try
- {
- _piece_came_in(index, pPieceBuf, begin, length);
- }
- catch (string& e)
- {
- assert(false);
- throw string(e);
- }
- }
- bool CStorageWrapperEx::_piece_came_in(long index, char *pPieceBuf, long begin, long length)
- {
- if (index >= m_vHave.size() || m_vHave[index] || m_vNumActive[index] <= 0 || begin <0)
- {
- bool bHave = m_vHave[index];
- long lNumAcive = m_vNumActive[index];
- assert(false);
- return false;
- }
- // If the index not in slits.
- if (m_mPlaces.find(index) == m_mPlaces.end())
- {
- if (!_FindPlaceForNewComeIndex(index, true))
- {
- assert(false);
- m_pMain->SetBadMsg("_FindPlaceForNewComeIndex error : ");
- return false;
- }
- }// endif dosn't exist.
- assert(m_mPlaces.find(index) != m_mPlaces.end());
- if (!_WriteIndexData(pPieceBuf, (BLONG)m_piece_length * (BLONG)m_mPlaces[index] + begin, length))
- return false;
- m_vNumActive[index] --;
- //
- // record the amount income of each uncompleted piece.
- //
- map<unsigned long, unsigned long>::iterator itAmount = m_mPartAmountIncome.find(index);
- if (itAmount == m_mPartAmountIncome.end())
- {
- m_mPartAmountIncome[index] = 0;
- }
- m_mPartAmountIncome[index] += length;
- //
- // check whether the piece completed.
- //
- if (!_do_I_have_requests(index) && !m_vNumActive[index])
- {
- //
- // if completed the amount completed tranfered to m_vHave.
- //
- itAmount = m_mPartAmountIncome.find(index);
- if (itAmount != m_mPartAmountIncome.end())
- m_mPartAmountIncome.erase(itAmount);
- if (!_check_single(index, true))
- return false;
- }
- return true;
- }
- bool CStorageWrapperEx::_FindPlaceForNewComeIndex(long index, bool bFirst)
- {
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- #ifdef _DEBUG
- if (m_vHoles.empty())
- {
- assert(false);
- return false;
- }
- #endif
- //////////////////////////////////////////////////////////////////////////////
- // get hole index from the holes list decided previous.
- // the hole index is caculated by the file range that the index belongs to.
- long lFileIndex = -1;
- bool bFind = false;
- for (int i=0; i<m_vRangeHoles.size(); i++)
- {
- if (index < m_vRangeHoles[i])
- {
- bFind = true;
- lFileIndex = i - 1;
- break;
- }
- }
- if (!bFind)
- lFileIndex = m_vRangeHoles.size() - 1;
- assert(lFileIndex >= 0);
- long lMinHoleIndex = m_vRangeHoles[lFileIndex];
- long lPopHoleIndex = -1;
- for (i=0; i<m_vHoles.size(); i++)
- {
- if (m_vHoles[i] >= lMinHoleIndex)
- {
- // lPopHoleIndex = (*pvHoles)[i];
- lPopHoleIndex = i;
- break;
- }
- }
- if (lPopHoleIndex < 0)
- {
- assert(false);
- return false;
- }
- // const int n = (*pvHoles)[0];
- const int n = m_vHoles[lPopHoleIndex];
- //////////////////////////////////////////////////////////////////////////////
- // if the hole is the first place of the file range.
- if (n == lMinHoleIndex && lFileIndex > 0)
- {
- long lfileoffset = m_vFileOffset[lFileIndex];
- long lPrePartIndex = m_vOffsetTrueIndex[lFileIndex];
- if (lfileoffset != 0 && lPrePartIndex >= 0)
- {
- char c = 'f';
- if (!m_pStorage->write(&c, (BLONG)lPrePartIndex * m_piece_length + lfileoffset - 1, sizeof(char)))
- return false;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // if the hole is took by next file offset part, move it to next index.
- if (lFileIndex < (m_vRangeHoles.size() - 1))
- {
- if (m_vOffsetTrueIndex[lFileIndex + 1] == n)
- {
- long lNextIndex = m_vRangeHoles[lFileIndex + 1];
- if (m_vOffsetTrueIndex[lFileIndex + 1] >= lNextIndex)
- {
- assert(false);
- return false;
- }
- //
- // tell whether the next file offset part filled, if yes move it.
- //
- // map<long, long>::iterator iter = m_mPlaces.find(lNextIndex);
- // if (iter != m_mPlaces.end())
- if (find(m_vHoles.begin(), m_vHoles.end(), lNextIndex) == m_vHoles.end())
- {
- if (!m_pStorage->read(pszBuf, (BLONG)m_piece_length * n, m_vFileOffset[lFileIndex + 1]))
- return false;
- if (!m_pStorage->write(pszBuf, (BLONG)m_piece_length * (n + 1), m_vFileOffset[lFileIndex + 1]))
- return false;
- }
- //
- // mark the offset to next index, no matter whether it is filled.
- //
- m_vOffsetTrueIndex[lFileIndex + 1] ++;
- if (m_vOffsetTrueIndex[lFileIndex + 1] >= lNextIndex)
- {
- m_vOffsetTrueIndex[lFileIndex + 1] = -1;
- }
- }
- }
- //////////////////////////////////////////////////////////////
- // find the index place, whether in holes or in place took by other piece.
- //
- long lIndexP = -1;
- if (find(m_vHoles.begin(), m_vHoles.end(), index) == m_vHoles.end())
- {
- for (map<long, long>::iterator j = m_mPlaces.begin(); j != m_mPlaces.end(); j++)
- {
- if ((*j).second == index)
- {
- lIndexP = (*j).first;
- break;
- }
- }
- if (j == m_mPlaces.end())
- {
- assert(false);
- return false;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // old code. find the piece data to fill the hole, to free the true space for new coming piece.
- map<long, long>::iterator iter = m_mPlaces.find(n);
- // The new hole poped is needed by item in temps.
- if (iter != m_mPlaces.end())
- {
- // Move data from temp to split newly created from holes.
- long lOldPos = (*iter).second;
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * lOldPos, _piecelen(n)))
- return false;
- if (!_WriteIndexData(pszBuf, (BLONG)m_piece_length * n, _piecelen(n)))
- return false;
- CheckAfterMoveing(n, pszBuf);
- m_mPlaces[n] = n;
- if(index == lOldPos || lIndexP < 0 )
- {
- m_mPlaces[index] = lOldPos;
- }
- else
- {
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * index, _piecelen(lIndexP)))
- return false;
- if (!_WriteIndexData(pszBuf, (BLONG)m_piece_length * lOldPos, _piecelen(lIndexP)))
- return false;
- m_mPlaces[lIndexP] = lOldPos;
- m_mPlaces[index] = index;
- }
- }
- else
- {
- if (index == n || lIndexP < 0)// index item out of space. find(m_vHoles.begin(), m_vHoles.end(), index) != m_vHoles.end())
- {
- memset(pszBuf, 0xff, _piecelen(n));
- if (!_WriteIndexData(pszBuf, (BLONG)m_piece_length * n, _piecelen(n)))
- return false;
- m_mPlaces[index] = n;
- }
- else // Move item in index space to hole poped. Insert index item in space allocated.
- {
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * index, _piecelen(lIndexP)))
- return false;
- if (!_WriteIndexData(pszBuf, (BLONG)m_piece_length * n, _piecelen(lIndexP)))
- return false;
- m_mPlaces[lIndexP] = n;
- m_mPlaces[index] = index;
- }// endif hole pop
- }
- //////////////////////////////////////////////////////////////////////////////
- // erase the poped hole from the needed or notneeded holes, and must erase from m_vHoles which is the base
- // to generate the needed and notneeded holes when user change setup of files to be and not deleted .
- {
- vector<long>::iterator it = find(m_vHoles.begin(), m_vHoles.end(), n);
- if (it == m_vHoles.end())
- {
- TRACE("sdfsdfrn");
- for (i=0; i<m_vHoles.size(); i++)
- {
- TRACE("%d, ", m_vHoles[i]);
- }
- TRACE("rn");
- assert(false);
- return false;
- }
- // TRACE("rn *********erase holes(%d, %d, %d) **********rn", iState, n, m_vHoles.size());
- m_vHoles.erase(it);
- }
- return true;
- }
- bool CStorageWrapperEx::_check_single(long index, bool check)
- {
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- assert(m_mPlaces.find(index) != m_mPlaces.end());
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * m_mPlaces[index], _piecelen(index)))
- {
- assert(false);
- return false;
- }
- unsigned char shasum[20] = {0};
- CSHA sha;
- sha.start();
- sha.update((unsigned char*)pszBuf, _piecelen(index));
- sha.finish(shasum);
- if (m_vHashs[index] == shasum)
- {
- m_vHave[index] = true;
- m_lAmountLeft -= _piecelen(index);
- m_vInactiveRequests[index].clear();
- m_vWasChecked[index] = m_bCheckHashes;
- if (!IsUnNeededIndex(index))
- {
- m_lPartAmountLeft -= _piecelen(index);
- if (m_lPartAmountLeft <= 0)
- {
- m_pMain->PartCompleted();
- }
- }
- if (m_lAmountLeft <= 0)
- {
- // todo : finished();
- m_pMain->Completed();
- }
- m_pMain->PutFractionsState(index, 1);
- }
- else
- {
- // todo: data_flunk().
- m_pMain->data_flunked(_piecelen(index));
- m_vInactiveRequests[index] = m_vNone;
- m_lAmountInactive += _piecelen(index);
- m_lPartAmountInactive += _GetRequestSize(index);
- m_pMain->PutFractionsState(index, 0);
- return false;
- }
- return true;
- }
- bool CStorageWrapperEx::CheckAfterMoveing(int iIndex, char* pszBuf)
- {
- if (m_bDoubleCheck && m_vHave[iIndex])
- {
- if (m_bTripleCheck)
- {
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * iIndex, _piecelen(iIndex), true))
- return false;
- }
- unsigned char shasum[20] = {0};
- CSHA sha;
- sha.start();
- sha.update((unsigned char*)pszBuf, _piecelen(iIndex));
- sha.finish(shasum);
- if (m_vHashs[iIndex] != shasum)
- {
- assert(false);
- // todo : failed('download corrupted; please restart and resume').
- m_pMain->SetBadMsg("download corrupted; please restart and resume");
- return false;
- }
- }
- return true;
- }
- /*************************************************************************************
- parameter :
- lAllocateRate : (n)M allocated per second.
- ************************************************************************************/
- bool CStorageWrapperEx::Create(CDownloaderFeedback* pMain,
- HANDLE hevDone, HANDLE hevUnPause, CStorageEx* pStorageEx, CDownloader* pDownloader, vector<char*>& vPieces,
- bool check_hashes, long request_size, long piece_length,
- eAllocType eAllocType,
- long lAllocateRate, bool m_bDoubleCheck, bool m_bTripleCheck)
- {
- assert(pMain && hevDone && pStorageEx && lAllocateRate > 0);
- m_pMain = pMain;
- m_hevDone = hevDone;
- m_hevUnPause = hevUnPause;
- m_pStorage = pStorageEx;
- m_pDownloader = pDownloader;
- for (int i=0; i<vPieces.size(); i++)
- {
- m_vHashs.push_back((const char* const)vPieces[i]);
- m_vNumActive.push_back(0);
- m_vInactiveRequests.push_back(m_vNone);
- m_vHave.push_back(false);
- // m_vStatActive.push_back(false);
- m_vWasChecked.push_back(check_hashes);
- }
- m_bCheckHashes = check_hashes;
- m_request_size = request_size;
- m_piece_length = piece_length;
- m_lTotalLength = m_pStorage->GetTotalLength();
- m_lAmountLeft = m_lTotalLength;
- m_lAmountInactive = m_lTotalLength;
- // m_lPartAmountInactive = m_vHave.size(); // useless, but temp initialize the member data.
- m_eAllocType = eAllocType;
- if (m_lTotalLength <= ((BLONG)(vPieces.size()-1) * piece_length))
- throw string("CStorageWrapper construct() error: bad data from tracker - total too small");
- if (m_lTotalLength > ((BLONG)vPieces.size() * piece_length))
- throw string("CStorageWrapper construct() error: bad data from tracker - total too big");
- if (m_vHashs.size() <= 0)
- {
- m_pMain->Completed();
- return true;
- }
- time(&m_tLast);
- m_tTimeSpan = m_piece_length / (lAllocateRate * 1048576);
- _FormatRangeHoles();
- m_pMain->ShowSystemMessage("检查已下载数据,可能占用较多系统资源,请稍后.", CSystemMsg::eCmd);
- m_pMain->ShowSystemMessage("开始检查...", CSystemMsg::eMsgOut);
- if (!CheckFiles())
- {
- m_pMain->SetStorageChecking(false);
- m_pMain->SetStorageAllocating(false);
- return false;
- }
- m_pMain->SetStorageChecking(false);
- m_pMain->SetStorageAllocating(false);
- //
- // Make UnNeeded files.
- //
- _MakeUnNeededIndexs();
- if (!IsEventSet(m_hevDone))
- {
- float fCompleted = 0;
- if (m_lTotalLength > 0)
- fCompleted = ((float)(m_lTotalLength - m_lAmountLeft)) / m_lTotalLength;
- m_pMain->SetCheckingDone(fCompleted, GetPartCompletedPercent());
- m_pMain->ShowSystemMessage("检查完成.", CSystemMsg::eMsgIn);
- }
- return true;
- }
- bool CStorageWrapperEx::CheckFiles()
- {
- map<CHashItem, long> mTargets;
- long lTotal = m_vHashs.size();
- //
- // compute the total length allocated to be checked,
- // but the critical index are skipped, it is a approximatetly value.
- //
- for (int i=0; i<m_vHashs.size(); i++)
- {
- if (!_waspre(i))
- {
- if (mTargets.find(m_vHashs[i]) == mTargets.end())
- mTargets[m_vHashs[i]] = i;
- else
- mTargets.erase(m_vHashs[i]);
- lTotal -= 1;
- }
- }
- if (lTotal && m_bCheckHashes)
- {
- // todo : notify begin check.
- m_pMain->SetStorageChecking(true);
- }
- long lNumChecked = 0;
- long lLastLen = _piecelen(m_vHashs.size() - 1);
- long lOutOfPlace = 0;
- long lUpdateNum = lTotal/300 + 1;
- long lUpdateCount = 0;
- bool bFirstFileIndex = true;
- bool bFirstNoPrepared = true;
- long lNextHoleIdx = 0;
- assert(m_vRangeHoles.size() == m_vFileOffset.size());
- for (i=0; i<m_vHashs.size(); i++)
- {
- bFirstFileIndex = false;
- bool bHaveNext = (lNextHoleIdx < (m_vRangeHoles.size()));
- if (bHaveNext)
- {
- if (i == m_vRangeHoles[lNextHoleIdx])
- {
- bFirstFileIndex = true;
- bFirstNoPrepared = true;
- lNextHoleIdx ++;
- }
- }
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- bool bSaveOffset = false;
- if (!_waspre(i))
- {
- if (bFirstFileIndex)
- {
- assert((lNextHoleIdx - 1 ) >= 0);
- long lcurIndex = lNextHoleIdx - 1;
- if (m_vOffsetTrueIndex[lcurIndex] >= 0)
- {
- if (m_pStorage->was_preallocated((BLONG)m_vOffsetTrueIndex[lcurIndex] * m_piece_length,
- (BLONG)m_vFileOffset[lcurIndex]) &&
- m_pStorage->was_preallocated((BLONG)i * m_piece_length + m_vFileOffset[lcurIndex],
- (BLONG)_piecelen(i) - m_vFileOffset[lcurIndex]))
- {
- m_vFileOffsetPreAllocated[lcurIndex] = true;
- bSaveOffset = true;
- }
- }
- }
- else if (bFirstNoPrepared)
- {
- bFirstNoPrepared = false;
- if (bHaveNext)
- m_vOffsetTrueIndex[lNextHoleIdx] = i;
- }
- if (!bSaveOffset)
- {
- if (!m_bCheckHashes)
- {
- // todo : told file complete on start-up, but data is missing.
- m_pMain->SetBadMsg("文件已被修改或移动,导致数据丢失,请重新下载."); // told file complete on start-up, but data is missing.");
- // assert(false);
- return false;
- }
- m_vHoles.push_back(i);
- continue;
- }
- }
- else if (!m_bCheckHashes)
- {
- markgot(i, i);
- continue;
- }
- //
- // if the piece space was allocated, then check the data of it whether be valid.
- //
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * i, _piecelen(i)))
- return false;
- unsigned char shaPart[20] = {0};
- unsigned char shaFull[20] = {0};
- CSHA sha;
- sha.start();
- sha.update((unsigned char*)pszBuf, lLastLen);
- sha.finish(shaPart);
- sha.start();
- sha.update((unsigned char*)pszBuf, _piecelen(i));
- sha.finish(shaFull);
- if (m_vHashs[i] == shaFull)
- {
- markgot(i, i);
- }
- else
- {
- map<CHashItem, long>::iterator iter = mTargets.find(CHashItem((const char* const)shaFull));
- if (iter != mTargets.end() &&
- _piecelen(i) == _piecelen((*iter).second))
- {
- markgot((*iter).second, i);
- mTargets.erase(iter);
- lOutOfPlace += 1;
- }
- else if (!m_vHave[m_vHave.size()-1] &&
- m_vHashs[m_vHashs.size() - 1] == shaPart &&
- ((i == (m_vHashs.size() - 1)) || !_waspre(m_vHashs.size() - 1)) )
- {
- markgot(m_vHashs.size() - 1, i);
- lOutOfPlace += 1;
- }
- else
- {
- m_mPlaces[i] = i;
- }
- }
- if (!IsEventSet(m_hevUnPause))
- {
- m_pMain->ShowSystemMessage("用户暂停该任务...", CSystemMsg::eCmd);
- DWORD dwRet = WaitForSingleObject(m_hevUnPause, INFINITE);
- m_pMain->ShowSystemMessage("用户继续该任务...", CSystemMsg::eCmd);
- }
- if (IsEventSet(m_hevDone))
- return false;
- if (!bSaveOffset)
- {
- lNumChecked ++;
- lUpdateCount ++;
- if (lUpdateCount >= lUpdateNum)
- {
- lUpdateCount = 0;
- if (lTotal > 0)
- m_pMain->SetStorageChecking(true, (float)lNumChecked / lTotal);
- }
- }
- } // end for
- // todo : Notify check complete.
- m_pMain->SetStorageChecking(false);
- m_pMain->PutFractions(m_vHave);
- ShowDetailsTest();
- if (m_lAmountLeft <= 0)
- {
- // todo : notify finished.
- m_pMain->Completed();
- }
- if (m_eAllocType == eAllocSparse)
- {
- m_pStorage->top_off();
- if (lOutOfPlace > 0)
- {
- // todo: statusfunc(activity = 'moving data', fractionDone = 1.0)
- long lToMove = lOutOfPlace;
- lUpdateNum = lOutOfPlace/300 + 1;
- lUpdateCount = 0;
- for (i=0; i<m_vHashs.size(); i++)
- {
- if (!IsEventSet(m_hevUnPause))
- {
- m_pMain->ShowSystemMessage("用户暂停该任务...", CSystemMsg::eCmd);
- DWORD dwRet = WaitForSingleObject(m_hevUnPause, INFINITE);
- m_pMain->ShowSystemMessage("用户继续该任务...", CSystemMsg::eCmd);
- }
- if (IsEventSet(m_hevDone))
- return false;
- if (m_mPlaces.find(i) == m_mPlaces.end())
- {
- m_mPlaces[i] = i;
- }
- else if (m_mPlaces[i] != i)
- {
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- if (!m_pStorage->read(pszBuf, (BLONG)m_piece_length * m_mPlaces[i], _piecelen(i)))
- return false;
- if (!m_pStorage->write(pszBuf, (BLONG)m_piece_length * i, _piecelen(i)))
- return false;
- // check move data result.
- if (!CheckAfterMoveing(i, pszBuf))
- return false;
- m_mPlaces[i] = i;
- lToMove --;
- lUpdateCount ++;
- if (lUpdateCount > lUpdateNum)
- {
- lUpdateCount = 0;
- // todo : statusfunc(fractionDone = float(tomove)/out_of_place)
- }
- m_pStorage->flush();
- // todo : statusfunc(fractionDone = 0.0)
- }
- } // endfor hashs
- }
- else
- {
- for (int i=0; i<m_vHoles.size(); i++)
- {
- long j = m_vHoles[i];
- m_mPlaces[j] = j;
- }
- } // endif outofplace
- TRACE("rn *** after Sparse ***********************rn");
- ShowDetailsTest();
- m_vHoles.clear();
- return true;
- } // endif sparse
- if (m_vHoles.empty())
- return true;
- //
- // Pre allocate space, mark all pieces un completed to correct index.
- //
- if (m_eAllocType == eAllocPreAllocate)
- {
- m_pMain->SetStorageAllocating(true);
- long lNumHoles = m_vHoles.size();
- lUpdateNum = lNumHoles/300 + 1;
- lUpdateCount = 0;
- while (!m_vHoles.empty())
- {
- if (!IsEventSet(m_hevUnPause))
- {
- m_pMain->ShowSystemMessage("用户暂停该任务...", CSystemMsg::eCmd);
- DWORD dwRet = WaitForSingleObject(m_hevUnPause, INFINITE);
- m_pMain->ShowSystemMessage("用户继续该任务...", CSystemMsg::eCmd);
- }
- if (IsEventSet(m_hevDone))
- return false;
- if (!_doalloc())
- return false;
- lUpdateCount ++;
- if (lUpdateCount > lUpdateNum)
- {
- lUpdateCount = 0;
- if (lNumHoles)
- m_pMain->SetStorageAllocating(true, (float)(m_vHoles.size())/lNumHoles);
- }
- }
- m_pStorage->flush();
- // todo : statusfunc(fractionDone = 0.0)
- m_pMain->SetStorageAllocating(false);
- return true;
- } // endif PreAllocate
- if (m_eAllocType == eAllocBackGound)
- {
- bgalloc();
- }
- return true;
- }
- void CStorageWrapperEx::OnIdle()
- {
- time_t t;
- time(&t);
- time_t tspan = t - m_tLast;
- assert(tspan >= 0);
- if (tspan < 0)
- m_tLast = t;
- if (tspan < m_tTimeSpan)
- return ;
- _MakeUnNeededIndexs();
- if (!m_bBgallocActive)
- return;
- _bgalloc();
- }
- bool CStorageWrapperEx::bgalloc()
- {
- /*
- if (!m_vHoles.empty() && !m_bBgallocEnabled) // useless when no need catch flush command.
- {
- m_bBgallocEnabled = true;
- }
- //*/
- m_bBgallocActive = true;
- return true;
- }
- bool CStorageWrapperEx::_bgalloc()
- {
- if (!m_vHoles.empty())
- {
- _doalloc();
- }
- else
- {
- m_pStorage->flush();
- m_bBgallocActive = false;
- }
- return true;
- }
- bool CStorageWrapperEx::_MakeOffsetToTruePlace(const long index, const long n)
- {
- //////////////////////////////////////////////////////////////////////////////
- // if the hole is took by next file offset part, move it to next index.
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- long lFileIndex = -1;
- bool bFind = false;
- for (int i=0; i<m_vRangeHoles.size(); i++)
- {
- if (index < m_vRangeHoles[i])
- {
- bFind = true;
- lFileIndex = i - 1;
- break;
- }
- }
- if (!bFind)
- lFileIndex = m_vRangeHoles.size() - 1;
- assert(lFileIndex >= 0);
- if (lFileIndex < (m_vRangeHoles.size() - 1))
- {
- if (m_vOffsetTrueIndex[lFileIndex + 1] == n)
- {
- long lNextIndex = m_vRangeHoles[lFileIndex + 1];
- if (m_vOffsetTrueIndex[lFileIndex + 1] >= lNextIndex)
- {
- assert(false);
- return false;
- }
- //
- // tell whether the next file offset part filled, if yes move it.
- //
- if (find(m_vHoles.begin(), m_vHoles.end(), lNextIndex) == m_vHoles.end())
- {
- if (!m_pStorage->read(pszBuf, (BLONG)m_piece_length * n, m_vFileOffset[lFileIndex + 1]))
- return false;
- if (!m_pStorage->write(pszBuf, (BLONG)m_piece_length * lNextIndex , m_vFileOffset[lFileIndex + 1]))
- return false;
- }
- //
- // mark the offset to next index, no matter whether it is filled.
- //
- m_vOffsetTrueIndex[lFileIndex + 1] = -1;
- }
- }
- return true;
- }
- bool CStorageWrapperEx::_doalloc()
- {
- if (m_vHoles.empty())
- {
- assert(false);
- return false;
- }
- int n = m_vHoles[0];
- m_vHoles.erase(m_vHoles.begin());
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- //
- // check to see whether the space is took by offset.
- //
- if (!_MakeOffsetToTruePlace(n, n))
- return false;
- map<long, long >::iterator iter = m_mPlaces.find(n);
- if (iter != m_mPlaces.end())
- {
- long lOldPos = (*iter).second;
- m_mPlaces[lOldPos] = lOldPos;
- if (!_ReadIndexData(pszBuf, (BLONG)m_piece_length * lOldPos, _piecelen(n)))
- return false;
- if (!_WriteIndexData(pszBuf, (BLONG)m_piece_length * n, _piecelen(n)))
- return false;
- // check move data result.
- if (!CheckAfterMoveing(n, pszBuf))
- return false;
- }
- else
- {
- memset(pszBuf, 0xff, m_piece_length);
- if (!_WriteIndexData(pszBuf, (BLONG)m_piece_length * n, _piecelen(n)))
- return false;
- }
- // allocate done.
- m_mPlaces[n] = n;
- return true;
- }
- bool CStorageWrapperEx::_waspre(int iIndex)
- {
- return m_pStorage->was_preallocated((BLONG)iIndex * m_piece_length, _piecelen(iIndex));
- }
- void CStorageWrapperEx::markgot(long iPiece, long lPos)
- {
- m_mPlaces[iPiece] = lPos;
- m_vHave[iPiece] = true;
- m_lAmountLeft -= _piecelen(iPiece);
- m_lAmountInactive -= _piecelen(iPiece);
- m_vInactiveRequests[iPiece].clear();
- m_vWasChecked[iPiece] = m_bCheckHashes;
- m_lStatNumfound ++;
- }
- long CStorageWrapperEx::_piecelen(int iPiece)
- {
- if (iPiece < (m_vHashs.size() - 1))
- return m_piece_length;
- return m_lTotalLength - ((BLONG)iPiece * m_piece_length);
- }
- void printHave(long x)
- {
- TRACE("%d, ", x);
- }
- void printPlace(pair<long, long> p)
- {
- TRACE("(%d, %d)", p.first, p.second);
- }
- void CStorageWrapperEx::ShowDetailsTest()
- {
- TRACE("rn places : {");
- for_each(m_mPlaces.begin(), m_mPlaces.end(), printPlace);
- TRACE("}rn");
- TRACE("rn have : {");
- for_each(m_vHave.begin(), m_vHave.end(), printHave);
- TRACE("}rn");
- TRACE("rn m_vHoles: {");
- for_each(m_vHoles.begin(), m_vHoles.end(), printHave);
- TRACE("}rn");
- TRACE("m_lAmountLeft : %d rn",m_lAmountLeft);
- TRACE("m_lAmountInactive : %d rn",m_lAmountInactive);
- }
- /*
- bool CStorageWrapperEx::_piece_came_in(long index, char *pPieceBuf, long begin, long length)
- {
- char* pszBuf = new char[m_piece_length];
- auto_ptr<char> aszBuf(pszBuf);
- if (m_vHoles.empty())
- {
- assert(false);
- return false;
- }
- //////////////////////////////////////////////////////////////
- // Get hole in needed files
- //
- /*
- // const int n = m_vHoles[0];
- // m_vHoles.erase(m_vHoles.begin());
- int iHoleIndex = -1;
- if (!IsUnNeededIndex(index))
- {
- for (int ih =0; ih<m_vHoles.size(); ih++)
- {
- if (!IsUnNeededIndex(m_vHoles[ih]))
- {
- iHoleIndex = m_vHoles[ih];
- m_vHoles.erase(m_vHoles.begin() + ih);
- break;
- }
- }
- }
- else
- {
- int iHoleIndex = m_vHoles[0];
- m_vHoles.erase(m_vHoles.begin());
- }
- // get hole fail.
- if (iHoleIndex < 0)
- {
- int iHoleIndex = m_vHoles[0];
- m_vHoles.erase(m_vHoles.begin());
- TRACE("rn***** get hole fail ******rn");
- assert(false);
- }
- const int n = iHoleIndex;
- map<long, long>::iterator iter = m_mPlaces.find(n);
- // The new hole poped is needed by item in temps.
- if (iter != m_mPlaces.end())
- {
- // Move data from temp to split newly created from holes.
- long lOldPos = (*iter).second;
- if (!m_pStorage->read(pszBuf, m_piece_length * lOldPos, _piecelen(n)))
- return false;
- if (!m_pStorage->write(pszBuf, m_piece_length * n, _piecelen(n)))
- return false;
- CheckAfterMoveing(n, pszBuf);
- m_mPlaces[n] = n;
- // Don't move, just specify the index item in the split newly created from holes.
- if (index == lOldPos ||
- find(m_vHoles.begin(), m_vHoles.end(), index) != m_vHoles.end())
- {
- m_mPlaces[index] = lOldPos;
- }
- else // Move data from split which take the place of index item.
- {
- long p = 0;
- for (map<long, long>::iterator j = m_mPlaces.begin(); j != m_mPlaces.end(); j++)
- {
- if ((*j).second == index)
- {
- p = (*j).first;
- break;
- }
- }
- if (j == m_mPlaces.end())
- {
- assert(false);
- return false;
- }
- if (!m_pStorage->read(pszBuf, m_piece_length * index, _piecelen(p)))
- return false;
- if (!m_pStorage->write(pszBuf, m_piece_length * lOldPos, _piecelen(p)))
- return false;
- m_mPlaces[p] = lOldPos;
- m_mPlaces[index] = index;
- }
- }
- else if (index == n || // index item out of space.
- find(m_vHoles.begin(), m_vHoles.end(), index) != m_vHoles.end())
- {
- memset(pszBuf, 0xff, _piecelen(n));
- if (!m_pStorage->write(pszBuf, m_piece_length * n, _piecelen(n)))
- return false;
- m_mPlaces[index] = n;
- }
- else // Move item in index space to hole poped. Insert index item in space allocated.
- {
- long p = 0;
- for (map<long, long>::iterator j = m_mPlaces.begin(); j != m_mPlaces.end(); j++)
- {
- if ((*j).second == index)
- {
- p = (*j).first;
- break;
- }
- }
- if (j == m_mPlaces.end())
- {
- assert(false);
- return false;
- }
- if (!m_pStorage->read(pszBuf, m_piece_length * index, _piecelen(p)))
- return false;
- if (!m_pStorage->write(pszBuf, m_piece_length * n, _piecelen(p)))
- return false;
- m_mPlaces[p] = n;
- m_mPlaces[index] = index;
- }// endif hole pop
- }
- //*/
- /*
- long CStorageWrapperEx::_GetMinHolesIndex(const long index)
- {
- if (m_vRangeHoles.size() <= 0)
- {
- assert(false);
- return -1;
- }
- for (int i=0; i<m_vRangeHoles.size(); i++)
- {
- if (index < m_vRangeHoles[i])
- {
- assert(i > 0);
- return m_vRangeHoles[i - 1];
- }
- }
- return m_vRangeHoles[m_vRangeHoles.size() - 1];
- // assert(false);
- return -1;
- }
- CSize CStorageWrapperEx::_GetFileOffset(const long index)
- {
- assert(m_vRangeHoles.size() == m_vFileOffset.size());
- for (int i=0; i<m_vRangeHoles.size(); i++)
- {
- if (index >= m_vRangeHoles[i])
- {
- if (i >= (m_vRangeHoles.size()-1))
- return CSize(-1, -1);
- return CSize (m_vRangeHoles[i+1], m_vFileOffset[i + 1]);
- }
- }
- assert(false);
- return -1;
- }
- //*/