int bbcp_File::Read_Vector(bbcp_BuffPool *iBP, bbcp_BuffPool *oBP, int vNum) { bbcp_Buffer *ioBuff[IOV_MAX]; struct iovec ioVec [IOV_MAX]; ssize_t blen, rlen; int rdsz = iBP->DataSize(), numV = (vNum > IOV_MAX ? IOV_MAX : vNum); int i, ivN, eof = 0; // Initialize transfer rate limiting if so desired // if (bbcp_Config.Xrate) Read_Wait(rdsz*numV); // Simply read one buffer at a time, that's the fastest way to do this // // cerr <<"VECTOR READ SIZE=" <<rdsz <<" v=" <<numV <<endl; while(!eof) { // Obtain buffers // for (ivN = 0; ivN < numV && bytesLeft > 0; ivN++) {if (!(ioBuff[ivN] = iBP->getEmptyBuff())) return -ENOBUFS; ioVec[ivN].iov_base = (caddr_t)(ioBuff[ivN]->data); ioVec[ivN].iov_len = (rdsz < bytesLeft ? rdsz : bytesLeft); bytesLeft -= rdsz; } // Read data into the buffer // if ((rlen = IOB->Read((const struct iovec *)&ioVec, ivN)) <= 0) {for (i = 0; i < ivN; i++) iBP->putEmptyBuff(ioBuff[i]); eof = !rlen; break; } // Queue a filled buffers for further processing // for (i = 0; i < ivN && rlen; i++) {blen = (rlen >= rdsz ? rdsz : rlen); ioBuff[i]->boff = nextoffset; nextoffset += blen; ioBuff[i]->blen = blen; rlen -= blen; oBP->putFullBuff(ioBuff[i]); } // Return any empty buffers // eof = i < ivN || bytesLeft <= 0; while(i < ivN) iBP->putEmptyBuff(ioBuff[i++]); // Limit Transfer rate if need be // if (PaceTime && !eof) Read_Wait(); } // All done // if (!eof) return (rlen ? static_cast<int>(rlen) : -ENODATA); return 0; }
int bbcp_File::Read_Normal(bbcp_BuffPool* iBP, bbcp_BuffPool* oBP) { bbcp_Buffer* bP; ssize_t rlen; int rdsz = iBP->DataSize(); // Initialize transfer rate limiting if so desired // if (bbcp_Config.Xrate) Read_Wait(rdsz); // Simply read one buffer at a time, that's the fastest way to do this // // cerr <<"NORMAL READ SIZE=" <<rdsz <<endl; do { // Do real-time copy if need be // if (rtCopy && (bytesLeft = bbcp_RTCopy.Prep(nextoffset, rdsz, rlen)) <= 0) break; // Obtain buffer // if (!(bP = iBP->getEmptyBuff())) return -ENOBUFS; // Read data into the buffer // if ((rlen = IOB->Read(bP->data, rdsz)) <= 0) { iBP->putEmptyBuff(bP); break; } // Queue a filled buffer for further processing // bytesLeft -= rlen; bP->boff = nextoffset; nextoffset += rlen; bP->blen = rlen; oBP->putFullBuff(bP); // Limit Transfer rate if need be // if (PaceTime && rlen == rdsz && bytesLeft > 0) Read_Wait(); } while (rlen == rdsz && bytesLeft > 0); // All done // if (bytesLeft) return (rlen ? static_cast<int>(rlen) : -ENODATA); return 0; }
int bbcp_File::Read_Direct(bbcp_BuffPool *iBP, bbcp_BuffPool *oBP) { bbcp_Buffer *bP; ssize_t rlen; int Trunc = 0, rdsz = iBP->DataSize(); // Initialize transfer rate limiting if so desired // if (bbcp_Config.Xrate) Read_Wait(rdsz); // Simply read one buffer at a time, that's the fastest way to do this // // cerr <<"DIRECT READ SIZE=" <<rdsz <<endl; while(bytesLeft > 0) { // Obtain buffer // if (!(bP = iBP->getEmptyBuff())) return -ENOBUFS; // Check if we are reading the last segment. Inflate it to the block // size value (we have room in the buffer) and indicate trunc() needed. // Otherwise, do a normal full-sized read. // if (bytesLeft < rdsz) {rdsz = bytesLeft + (blockSize - 1) & ~(blockSize - 1); if ((rlen = IOB->Read(bP->data, rdsz)) < bytesLeft) {iBP->putEmptyBuff(bP); break;} Trunc = 1; rlen = bytesLeft; } else { if ((rlen = IOB->Read(bP->data, rdsz)) <= 0) {iBP->putEmptyBuff(bP); break;} } // Queue a filled buffer for further processing // bytesLeft -= rlen; bP->boff = nextoffset; nextoffset += rlen; bP->blen = rlen; oBP->putFullBuff(bP); // Limit Transfer rate if need be // if (PaceTime && bytesLeft > 0) Read_Wait(); } // All done // if (bytesLeft) return (rlen ? static_cast<int>(rlen) : -ENODATA); return 0; }
int bbcp_File::Read_Pipe(bbcp_BuffPool* iBP, bbcp_BuffPool* oBP) { bbcp_Buffer* bP; ssize_t rlen; int rdsz = iBP->DataSize(); // Initialize transfer rate limiting if so desired // if (bbcp_Config.Xrate) Read_Wait(rdsz); // Simply read one buffer at a time, that's the fastest way to do this // // cerr <<"PIPE READ SIZE=" <<rdsz <<endl; do { // Obtain buffer // if (!(bP = iBP->getEmptyBuff())) return -ENOBUFS; // Read data into the buffer // if ((rlen = IOB->Read(bP->data, rdsz)) <= 0) { iBP->putEmptyBuff(bP); break; } // Queue a filled buffer for further processing // bP->boff = nextoffset; nextoffset += rlen; bP->blen = rlen; oBP->putFullBuff(bP); // Limit Transfer rate if need be // if (PaceTime && rlen == rdsz) Read_Wait(); } while (rlen == rdsz); // All done // return 0; }