现在的位置: 首页 > 综合 > 正文

减少libtorrent的内存使用和让libtorrent支持ntfs

2014年01月15日 ⁄ 综合 ⁄ 共 5602字 ⁄ 字号 评论关闭

libtorrent有时候消耗内存很多 (原因是有些chunck size是4M, 申请10几个块就几十MB了),我们的机顶盒受不了.

另外libtorrent不支持ntfs分区.

所以....改!

 

一个chunk 4M,机顶盒吃不消,继续修改ing..,基本的原理就是要用到才读,用完又写回硬盘. 硬盘辛苦一点了.

memry_chunk增加构造函数

C++代码
  1. #ifdef LITTLE_MM   
  2.    MemoryChunk (int fd,  uint64_t file_offset, uint32_t len, int prot, int flags);   
  3. #endif  

增加函数, 用于获取部分chunk内容以及是否chunk

C++代码
  1. #ifdef LITTLE_MM   
  2.      /**  
  3.             Date:2010-07-27 add by aya  
  4.            **/  
  5.      void set_chunk_data (char* data, uinit32_t offset, uinit32_t len);   
  6.      char* get_chunk_data (uint32_t offset, uint32_t len);   
  7.      void release_chunk_data ();   
  8. #endif  

 

增加成员

C++代码
  1. #ifdef LITTLE_MM   
  2.     uint32_t m_chunk_len;   
  3.    char* m_data_ptr;   
  4. uint32_t m_data_len;   
  5. uint32_t m_data_offset;   
  6. bool m_is_valid;   
  7. #endif  

修改构造函数

C++代码
  1.  MemoryChunk() {   
  2.     #ifdef LITTLE_MM   
  3. m_fd = -1;   
  4. m_file_offset = 0;   
  5. m_chunk_len = 0;   
  6. m_data_ptr = NULL;   
  7. m_data_len = 0;   
  8. m_data_offset = 0;   
  9. m_ptr = NULL;       
  10. m_begin = NULL;     
  11. m_end = NULL;   
  12. m_is_valid = false;   
  13. #endif   
  14.     clear();    
  15.  }  

修改size函数

C++代码
  1.  uint32_t            size() const {   
  2. ifdef LITTLE_MM   
  3. return m_chunk_len;   
  4. else  
  5.     return m_end - m_begin;   
  6. endif   
  7.  }  

修改unmap函数

C++代码
  1. void  
  2. MemoryChunk::unmap() {   
  3.   if (!is_valid())   
  4.     throw internal_error("MemoryChunk::unmap() called on an invalid object");   
  5.   
  6. #if  !defined(MM_PRI) && !defined(LITTLE_MM)   
  7.   if (munmap(m_ptr, m_end - m_ptr) != 0)   
  8.     throw internal_error("MemoryChunk::unmap() system call failed: " + std::string(rak::error_number::current().c_str()));   
  9. #elif defined (MM_PRI)   
  10.     delete []m_ptr;   
  11. #endif   
  12. }    

修改sync函数

C++代码
  1. bool  
  2. MemoryChunk::sync(uint32_t offset, uint32_t length, int flags) {   
  3.   if (!is_valid())   
  4.     throw internal_error("Called MemoryChunk::sync() on an invalid object");   
  5.   
  6.   if (!is_valid_range(offset, length))   
  7.     throw internal_error("MemoryChunk::sync(...) received out-of-range input");   
  8.   
  9. #if !defined(MM_PRI) && !defined(LITTLE_MM)   
  10.   align_pair(&offset, &length);   
  11.   return msync(m_ptr + offset, length, flags) == 0;   
  12. #elif defined (MM_PRI)   
  13.   if (-1 == lseek (m_fd, m_file_offset + offset, SEEK_SET)) {       
  14.     return false;       
  15.   }       
  16.   return -1 != write (m_fd, m_ptr + offset, length);   
  17. #else   
  18.   return true;   
  19. #endif   
  20. }       

修改SocketFile::create_chunk

C++代码
  1. MemoryChunk   
  2. SocketFile::create_chunk(uint64_t offset, uint32_t length, int prot, int flags) const {   
  3.   if (!is_open())   
  4.     throw internal_error("SocketFile::get_chunk() called on a closed file");   
  5.   
  6.   // For some reason mapping beyond the extent of the file does not   
  7.   // cause mmap to complain, so we need to check manually here.   
  8.   if (offset < 0 || length == 0 || offset > size() || offset + length > size())   
  9.     return MemoryChunk();   
  10.   
  11. #if !defined(MM_PRI) && !defined(LITTLE_MM)   
  12.   uint64_t align = offset % MemoryChunk::page_size();   
  13.   
  14.   char* ptr = (char*)mmap(NULL, length + align, prot, flags, m_fd, offset - align);   
  15.      
  16.   if (ptr == MAP_FAILED)   
  17.     return MemoryChunk();   
  18.   return MemoryChunk(ptr, ptr + align, ptr + align + length, prot, flags);   
  19. #elif defined(MM_PRI)   
  20.   char* ptr = new char [length];   
  21.   lseek (m_fd, offset, SEEK_SET);   
  22.   if (length != read(m_fd, ptr, length)) {   
  23.     printf ("[SocketFile][read][ʧ°Ü]/n");   
  24.     delete []ptr;   
  25.     return MemoryChunk();   
  26.   } else {   
  27.     return MemoryChunk (m_fd, offset, ptr, ptr, ptr + length, prot, flags);   
  28.   }   
  29. #else   
  30.    return MemoryChunk (m_fd, offset, length, prot, flags);   
  31. #endif   
  32. }   

 

修改 HashChunk::perform_part

C++代码
  1. uint32_t   
  2. HashChunk::perform_part(Chunk::iterator itr, uint32_t length) {   
  3.   length = std::min(length, remaining_part(itr, m_position));   
  4. #ifndef LITTLE_MM   
  5.   m_hash.update(itr->chunk().begin() + , );   
  6. #else   
  7.  m_hash.update(itr->chunk().get_chunk_data (m_position - itr->position(), length), length);   
  8.  itr->chunk().release_chunk_data ();   
  9. #endif   
  10.   m_position += length;   
  11.   return length;   
  12. }  

修改Chunk::incore_length

C++代码
  1. uint32_t   
  2. Chunk::incore_length(uint32_t pos) {   
  3. #ifndef LITTLE_MM   
  4.   uint32_t lengthIncore = 0;   
  5.   iterator itr = at_position(pos);   
  6.   
  7.   if (itr == end())   
  8.     throw internal_error("Chunk::incore_length(...) at end()");   
  9.   
  10.   do {   
  11.     uint32_t length = itr->incore_length(pos);   
  12.   
  13.     pos += length;   
  14.     lengthIncore += length;   
  15.   
  16.   } while (pos == itr->position() + itr->size() && ++itr != end());   
  17.   
  18.   return lengthIncore;   
  19. #else   
  20.     return 0;   
  21. #endif   
  22. }  

修改 ChunkIterator的三个函数

C++代码
  1. inline Chunk::data_type   
  2. ChunkIterator::data() {   
  3.   Chunk::data_type data = m_chunk->at_memory(m_first, m_iterator);   
  4.   data.second = std::min(data.second, m_last - m_first);   
  5.  #ifndef LITTLE_MM   
  6.   return data;   
  7.  #else   
  8.   data.first = m_iterator->chunk().get_chunk_data ((uint32_t)data.first, data.second);   
  9.   return data;   
  10.  #endif   
  11. }   
  12.   
  13. inline bool  
  14. ChunkIterator::next() {   
  15. #ifdef LITTLE_MM   
  16.   m_iterator->chunk().release_chunk_data ();   
  17. #endif   
  18.   
  19.   m_first = m_iterator->position() + m_iterator->size();   
  20.   while (++m_iterator != m_chunk->end()) {   
  21.     if (m_iterator->size() != 0)   
  22.       return m_first < m_last;   
  23.   }   
  24.   
  25.   return false;   
  26. }   
  27.   
  28. // Returns true if the new position is on a file boundary while not at   
  29. // the edges of the chunk.   
  30. //   
  31. // Do not return true if the length was zero, in order to avoid   
  32. // getting stuck looping when no data is being read/written.   
  33. inline bool  
  34. ChunkIterator::forward(uint32_t length) {   
  35. #ifdef LITTLE_MM   
  36.       m_iterator->chunk().release_chunk_data ();   
  37. #endif   
  38.   m_first += length;   
  39.   
  40.   if (m_first >= m_last)   
  41.     return false;   
  42.   
  43.   do {   
  44.     if (m_first < m_iterator->position() + m_iterator->size())   
  45.       return true;   
  46.   
  47.     m_iterator++;   
  48.   } while (m_iterator != m_chunk->end());   
  49.   
  50.   return false;   
  51. }   

 

 

经过测试, 添加多少下载任务都没事了.不会爆内存了.

 

抱歉!评论已关闭.