|
@@ -525,60 +525,78 @@ IntSequence parseIntRange(const std::string& src)
|
|
|
return values;
|
|
|
}
|
|
|
|
|
|
+static void computeHeadPieces
|
|
|
+(std::vector<size_t>& indexes,
|
|
|
+ const std::vector<SharedHandle<FileEntry> >& fileEntries,
|
|
|
+ size_t pieceLength,
|
|
|
+ uint64_t head)
|
|
|
+{
|
|
|
+ if(head == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
|
|
|
+ fileEntries.begin(); fi != fileEntries.end(); ++fi) {
|
|
|
+ if((*fi)->getLength() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ size_t lastIndex =
|
|
|
+ ((*fi)->getOffset()+std::min(head, (*fi)->getLength())-1)/pieceLength;
|
|
|
+ for(size_t index = (*fi)->getOffset()/pieceLength;
|
|
|
+ index <= lastIndex; ++index) {
|
|
|
+ indexes.push_back(index);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void computeTailPieces
|
|
|
+(std::vector<size_t>& indexes,
|
|
|
+ const std::vector<SharedHandle<FileEntry> >& fileEntries,
|
|
|
+ size_t pieceLength,
|
|
|
+ uint64_t tail)
|
|
|
+{
|
|
|
+ if(tail == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
|
|
|
+ fileEntries.begin(); fi != fileEntries.end(); ++fi) {
|
|
|
+ if((*fi)->getLength() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ uint64_t endOffset = (*fi)->getLastOffset();
|
|
|
+ size_t fromIndex =
|
|
|
+ (endOffset-1-(std::min(tail, (*fi)->getLength())-1))/pieceLength;
|
|
|
+ for(size_t index = fromIndex; index <= (endOffset-1)/pieceLength;
|
|
|
+ ++index) {
|
|
|
+ indexes.push_back(index);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void parsePrioritizePieceRange
|
|
|
(std::vector<size_t>& result, const std::string& src,
|
|
|
const std::vector<SharedHandle<FileEntry> >& fileEntries,
|
|
|
size_t pieceLength)
|
|
|
{
|
|
|
+ const uint64_t DEFAULT_SIZE = 1024*1024;
|
|
|
std::vector<size_t> indexes;
|
|
|
std::vector<std::string> parts;
|
|
|
split(src, std::back_inserter(parts), ",", true);
|
|
|
for(std::vector<std::string>::const_iterator i = parts.begin();
|
|
|
i != parts.end(); ++i) {
|
|
|
if((*i) == "head") {
|
|
|
- for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
|
|
|
- fileEntries.begin(); fi != fileEntries.end(); ++fi) {
|
|
|
- indexes.push_back((*fi)->getOffset()/pieceLength);
|
|
|
- }
|
|
|
+ computeHeadPieces(indexes, fileEntries, pieceLength, DEFAULT_SIZE);
|
|
|
} else if(util::startsWith(*i, "head=")) {
|
|
|
std::string sizestr = std::string((*i).begin()+(*i).find("=")+1,
|
|
|
(*i).end());
|
|
|
- uint64_t head = std::max((int64_t)0, getRealSize(sizestr));
|
|
|
- for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
|
|
|
- fileEntries.begin(); fi != fileEntries.end(); ++fi) {
|
|
|
- if((*fi)->getLength() == 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- size_t lastIndex =
|
|
|
- ((*fi)->getOffset()+std::min(head, (*fi)->getLength())-1)/pieceLength;
|
|
|
- for(size_t index = (*fi)->getOffset()/pieceLength;
|
|
|
- index <= lastIndex; ++index) {
|
|
|
- indexes.push_back(index);
|
|
|
- }
|
|
|
- }
|
|
|
+ computeHeadPieces(indexes, fileEntries, pieceLength,
|
|
|
+ std::max((int64_t)0, getRealSize(sizestr)));
|
|
|
} else if((*i) == "tail") {
|
|
|
- for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
|
|
|
- fileEntries.begin(); fi != fileEntries.end(); ++fi) {
|
|
|
- indexes.push_back
|
|
|
- (((*fi)->getOffset()+(*fi)->getLength()-1)/pieceLength);
|
|
|
- }
|
|
|
+ computeHeadPieces(indexes, fileEntries, pieceLength, DEFAULT_SIZE);
|
|
|
} else if(util::startsWith(*i, "tail=")) {
|
|
|
std::string sizestr = std::string((*i).begin()+(*i).find("=")+1,
|
|
|
(*i).end());
|
|
|
- uint64_t tail = std::max((int64_t)0, getRealSize(sizestr));
|
|
|
- for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
|
|
|
- fileEntries.begin(); fi != fileEntries.end(); ++fi) {
|
|
|
- if((*fi)->getLength() == 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- uint64_t endOffset = (*fi)->getLastOffset();
|
|
|
- size_t fromIndex =
|
|
|
- (endOffset-1-(std::min(tail, (*fi)->getLength())-1))/pieceLength;
|
|
|
- for(size_t index = fromIndex; index <= (endOffset-1)/pieceLength;
|
|
|
- ++index) {
|
|
|
- indexes.push_back(index);
|
|
|
- }
|
|
|
- }
|
|
|
+ computeTailPieces(indexes, fileEntries, pieceLength,
|
|
|
+ std::max((int64_t)0, getRealSize(sizestr)));
|
|
|
} else {
|
|
|
throw DL_ABORT_EX
|
|
|
(StringFormat("Unrecognized token %s", (*i).c_str()).str());
|