diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2008-06-15 16:19:06 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2008-06-15 16:19:06 +0000 |
| commit | 2f8e184fe5c8b8264fd0219ba2001be84c148d54 (patch) | |
| tree | afc7be78df791756df1a7f02974779372faec6e1 /src/MultiDiskAdaptor.cc | |
| parent | f9988a4ef6d769e5bb3fff2904622567fed72215 (diff) | |
2008-06-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Create only requested files and files which shares a piece with
requested file in multi-torrent downloads. Directory structures
are
also created in the same rule.
MultiDiskAdaptor::fileExists() now uses FileEntry instead of
DiskWriterEntry as in the previous implementation.
* src/MultiDiskWriter.cc
* src/MultiFileAllocationIterator.cc
* src/MultiFileAllocationIterator.h
* test/MultiFileAllocationIteratorTest.cc
Diffstat (limited to 'src/MultiDiskAdaptor.cc')
| -rw-r--r-- | src/MultiDiskAdaptor.cc | 99 |
1 files changed, 77 insertions, 22 deletions
diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc index dc59830a..a9ad762f 100644 --- a/src/MultiDiskAdaptor.cc +++ b/src/MultiDiskAdaptor.cc @@ -149,20 +149,77 @@ MultiDiskAdaptor::MultiDiskAdaptor(): MultiDiskAdaptor::~MultiDiskAdaptor() {} +static SharedHandle<DiskWriterEntry> createDiskWriterEntry +(const SharedHandle<FileEntry>& fileEntry, + DiskWriterFactory& dwFactory, + bool directIOAllowed) +{ + SharedHandle<DiskWriterEntry> entry(new DiskWriterEntry(fileEntry)); + entry->setDiskWriter(dwFactory.newDiskWriter()); + entry->getDiskWriter()->setDirectIOAllowed(directIOAllowed); + + return entry; +} + + void MultiDiskAdaptor::resetDiskWriterEntries() { diskWriterEntries.clear(); - for(FileEntries::const_iterator itr = fileEntries.begin(); - itr != fileEntries.end(); itr++) { - DiskWriterEntryHandle entry(new DiskWriterEntry(*itr)); - if((*itr)->isRequested()) { - entry->setDiskWriter(DefaultDiskWriterFactory().newDiskWriter()); - } else { - SharedHandle<DiskWriter> dw(new DefaultDiskWriter()); - entry->setDiskWriter(dw); + + if(fileEntries.empty()) { + return; + } + + DefaultDiskWriterFactory dwFactory; + if(pieceLength == 0) { + for(std::deque<SharedHandle<FileEntry> >::const_iterator itr = + fileEntries.begin(); itr != fileEntries.end(); ++itr) { + if((*itr)->isRequested()) { + diskWriterEntries.push_back + (createDiskWriterEntry(*itr, dwFactory, _directIOAllowed)); + } + } + } else { + std::deque<SharedHandle<FileEntry> >::const_iterator done = fileEntries.begin(); + for(std::deque<SharedHandle<FileEntry> >::const_iterator itr = + fileEntries.begin(); itr != fileEntries.end();) { + if(!(*itr)->isRequested()) { + ++itr; + continue; + } + off_t pieceStartOffset = ((*itr)->getOffset()/pieceLength)*pieceLength; + std::deque<SharedHandle<DiskWriterEntry> >::iterator insertionPoint = + diskWriterEntries.end(); + + if(itr != fileEntries.begin()) { + for(std::deque<SharedHandle<FileEntry> >::const_iterator i = itr-1; + i != done; --i) { + if((uint64_t)pieceStartOffset < (*i)->getOffset()+(*i)->getLength()) { + insertionPoint = diskWriterEntries.insert + (insertionPoint, + createDiskWriterEntry(*i, dwFactory, _directIOAllowed)); + } else { + break; + } + } + } + + diskWriterEntries.push_back + (createDiskWriterEntry(*itr, dwFactory, _directIOAllowed)); + + ++itr; + + for(; itr != fileEntries.end(); ++itr) { + if((*itr)->getOffset() < pieceStartOffset+pieceLength) { + diskWriterEntries.push_back + (createDiskWriterEntry(*itr, dwFactory, _directIOAllowed)); + } else { + break; + } + } + + done = itr-1; } - entry->getDiskWriter()->setDirectIOAllowed(_directIOAllowed); - diskWriterEntries.push_back(entry); } } @@ -173,9 +230,9 @@ std::string MultiDiskAdaptor::getTopDirPath() const void MultiDiskAdaptor::mkdir(const std::string& topDirPath) const { - for(FileEntries::const_iterator itr = fileEntries.begin(); - itr != fileEntries.end(); itr++) { - (*itr)->setupDir(topDirPath); + for(std::deque<SharedHandle<DiskWriterEntry> >::const_iterator i = + diskWriterEntries.begin(); i != diskWriterEntries.end(); ++i) { + (*i)->getFileEntry()->setupDir(topDirPath); } } @@ -211,16 +268,16 @@ void MultiDiskAdaptor::openIfNot void MultiDiskAdaptor::openFile() { _cachedTopDirPath = getTopDirPath(); - mkdir(_cachedTopDirPath); resetDiskWriterEntries(); + mkdir(_cachedTopDirPath); // TODO we should call openIfNot here? } void MultiDiskAdaptor::initAndOpenFile() { _cachedTopDirPath = getTopDirPath(); - mkdir(_cachedTopDirPath); resetDiskWriterEntries(); + mkdir(_cachedTopDirPath); // Call DiskWriterEntry::initAndOpenFile to make files truncated. for(DiskWriterEntries::iterator itr = diskWriterEntries.begin(); itr != diskWriterEntries.end(); ++itr) { @@ -339,17 +396,15 @@ ssize_t MultiDiskAdaptor::readData(unsigned char* data, size_t len, off_t offset bool MultiDiskAdaptor::fileExists() { - if(diskWriterEntries.empty()) { - resetDiskWriterEntries(); - } // Don't use _cachedTopDirPath because they are initialized after opening files. // This method could be called before opening files. std::string topDirPath = getTopDirPath(); - for(DiskWriterEntries::iterator itr = diskWriterEntries.begin(); - itr != diskWriterEntries.end(); ++itr) { - if((*itr)->fileExists(topDirPath)) { + for(std::deque<SharedHandle<FileEntry> >::iterator i = + fileEntries.begin(); i != fileEntries.end(); ++i) { + + if(File(topDirPath+"/"+(*i)->getPath()).isFile()) { return true; - } + } } return false; } |
