libtorrent有时候消耗内存很多 (原因是有些chunck size是4M, 申请10几个块就几十MB了),我们的机顶盒受不了.
另外libtorrent不支持ntfs分区.
所以....改!
一个chunk 4M,机顶盒吃不消,继续修改ing..,基本的原理就是要用到才读,用完又写回硬盘. 硬盘辛苦一点了.
memry_chunk增加构造函数
C++代码
- #ifdef LITTLE_MM
- MemoryChunk (int fd, uint64_t file_offset, uint32_t len, int prot, int flags);
- #endif
增加函数, 用于获取部分chunk内容以及是否chunk
C++代码
- #ifdef LITTLE_MM
- /**
- Date:2010-07-27 add by aya
- **/
- void set_chunk_data (char* data, uinit32_t offset, uinit32_t len);
- char* get_chunk_data (uint32_t offset, uint32_t len);
- void release_chunk_data ();
- #endif
增加成员
C++代码
- #ifdef LITTLE_MM
- uint32_t m_chunk_len;
- char* m_data_ptr;
- uint32_t m_data_len;
- uint32_t m_data_offset;
- bool m_is_valid;
- #endif
修改构造函数
C++代码
- MemoryChunk() {
- #ifdef LITTLE_MM
- m_fd = -1;
- m_file_offset = 0;
- m_chunk_len = 0;
- m_data_ptr = NULL;
- m_data_len = 0;
- m_data_offset = 0;
- m_ptr = NULL;
- m_begin = NULL;
- m_end = NULL;
- m_is_valid = false;
- #endif
- clear();
- }
修改size函数
C++代码
- uint32_t size() const {
- ifdef LITTLE_MM
- return m_chunk_len;
- else
- return m_end - m_begin;
- endif
- }
修改unmap函数
C++代码
- void
- MemoryChunk::unmap() {
- if (!is_valid())
- throw internal_error("MemoryChunk::unmap() called on an invalid object");
- #if !defined(MM_PRI) && !defined(LITTLE_MM)
- if (munmap(m_ptr, m_end - m_ptr) != 0)
- throw internal_error("MemoryChunk::unmap() system call failed: " + std::string(rak::error_number::current().c_str()));
- #elif defined (MM_PRI)
- delete []m_ptr;
- #endif
- }
修改sync函数
C++代码
- bool
- MemoryChunk::sync(uint32_t offset, uint32_t length, int flags) {
- if (!is_valid())
- throw internal_error("Called MemoryChunk::sync() on an invalid object");
- if (!is_valid_range(offset, length))
- throw internal_error("MemoryChunk::sync(...) received out-of-range input");
- #if !defined(MM_PRI) && !defined(LITTLE_MM)
- align_pair(&offset, &length);
- return msync(m_ptr + offset, length, flags) == 0;
- #elif defined (MM_PRI)
- if (-1 == lseek (m_fd, m_file_offset + offset, SEEK_SET)) {
- return false;
- }
- return -1 != write (m_fd, m_ptr + offset, length);
- #else
- return true;
- #endif
- }
修改SocketFile::create_chunk
C++代码
- MemoryChunk
- SocketFile::create_chunk(uint64_t offset, uint32_t length, int prot, int flags) const {
- if (!is_open())
- throw internal_error("SocketFile::get_chunk() called on a closed file");
- // For some reason mapping beyond the extent of the file does not
- // cause mmap to complain, so we need to check manually here.
- if (offset < 0 || length == 0 || offset > size() || offset + length > size())
- return MemoryChunk();
- #if !defined(MM_PRI) && !defined(LITTLE_MM)
- uint64_t align = offset % MemoryChunk::page_size();
- char* ptr = (char*)mmap(NULL, length + align, prot, flags, m_fd, offset - align);
- if (ptr == MAP_FAILED)
- return MemoryChunk();
- return MemoryChunk(ptr, ptr + align, ptr + align + length, prot, flags);
- #elif defined(MM_PRI)
- char* ptr = new char [length];
- lseek (m_fd, offset, SEEK_SET);
- if (length != read(m_fd, ptr, length)) {
- printf ("[SocketFile][read][ʧ°Ü]/n");
- delete []ptr;
- return MemoryChunk();
- } else {
- return MemoryChunk (m_fd, offset, ptr, ptr, ptr + length, prot, flags);
- }
- #else
- return MemoryChunk (m_fd, offset, length, prot, flags);
- #endif
- }
修改 HashChunk::perform_part
C++代码
- uint32_t
- HashChunk::perform_part(Chunk::iterator itr, uint32_t length) {
- length = std::min(length, remaining_part(itr, m_position));
- #ifndef LITTLE_MM
- m_hash.update(itr->chunk().begin() + , );
- #else
- m_hash.update(itr->chunk().get_chunk_data (m_position - itr->position(), length), length);
- itr->chunk().release_chunk_data ();
- #endif
- m_position += length;
- return length;
- }
修改Chunk::incore_length
C++代码
- uint32_t
- Chunk::incore_length(uint32_t pos) {
- #ifndef LITTLE_MM
- uint32_t lengthIncore = 0;
- iterator itr = at_position(pos);
- if (itr == end())
- throw internal_error("Chunk::incore_length(...) at end()");
- do {
- uint32_t length = itr->incore_length(pos);
- pos += length;
- lengthIncore += length;
- } while (pos == itr->position() + itr->size() && ++itr != end());
- return lengthIncore;
- #else
- return 0;
- #endif
- }
修改 ChunkIterator的三个函数
C++代码
- inline Chunk::data_type
- ChunkIterator::data() {
- Chunk::data_type data = m_chunk->at_memory(m_first, m_iterator);
- data.second = std::min(data.second, m_last - m_first);
- #ifndef LITTLE_MM
- return data;
- #else
- data.first = m_iterator->chunk().get_chunk_data ((uint32_t)data.first, data.second);
- return data;
- #endif
- }
- inline bool
- ChunkIterator::next() {
- #ifdef LITTLE_MM
- m_iterator->chunk().release_chunk_data ();
- #endif
- m_first = m_iterator->position() + m_iterator->size();
- while (++m_iterator != m_chunk->end()) {
- if (m_iterator->size() != 0)
- return m_first < m_last;
- }
- return false;
- }
- // Returns true if the new position is on a file boundary while not at
- // the edges of the chunk.
- //
- // Do not return true if the length was zero, in order to avoid
- // getting stuck looping when no data is being read/written.
- inline bool
- ChunkIterator::forward(uint32_t length) {
- #ifdef LITTLE_MM
- m_iterator->chunk().release_chunk_data ();
- #endif
- m_first += length;
- if (m_first >= m_last)
- return false;
- do {
- if (m_first < m_iterator->position() + m_iterator->size())
- return true;
- m_iterator++;
- } while (m_iterator != m_chunk->end());
- return false;
- }
经过测试, 添加多少下载任务都没事了.不会爆内存了.