mirror of https://github.com/aria2/aria2
SocketRecvBuffer: Eliminate memmove
Since we don't try to read into buffer if buffer is not empty, we don't have to memmove things. This commit mostly rewrites SocketRecvBuffer.pull/365/head
parent
8ed8ac0fe8
commit
692a674fe0
|
@ -187,7 +187,7 @@ bool DownloadCommand::executeInternal() {
|
|||
getSocketRecvBuffer()->getBufferLength());
|
||||
bufSize = streamFilter_->getBytesProcessed();
|
||||
}
|
||||
getSocketRecvBuffer()->shiftBuffer(bufSize);
|
||||
getSocketRecvBuffer()->drain(bufSize);
|
||||
peerStat_->updateDownloadLength(bufSize);
|
||||
getDownloadContext()->updateDownloadLength(bufSize);
|
||||
}
|
||||
|
|
|
@ -157,12 +157,12 @@ std::unique_ptr<HttpResponse> HttpConnection::receiveResponse()
|
|||
httpResponse->setHttpHeader(proc->getResult());
|
||||
httpResponse->setHttpRequest(outstandingHttpRequests_.front()->
|
||||
popHttpRequest());
|
||||
socketRecvBuffer_->shiftBuffer(proc->getLastBytesProcessed());
|
||||
socketRecvBuffer_->drain(proc->getLastBytesProcessed());
|
||||
outstandingHttpRequests_.pop_front();
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
socketRecvBuffer_->shiftBuffer(proc->getLastBytesProcessed());
|
||||
socketRecvBuffer_->drain(proc->getLastBytesProcessed());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ bool HttpServer::receiveRequest()
|
|||
lastRequestHeader_ = headerProcessor_->getResult();
|
||||
A2_LOG_INFO(fmt("HTTP Server received request\n%s",
|
||||
headerProcessor_->getHeaderString().c_str()));
|
||||
socketRecvBuffer_->shiftBuffer(headerProcessor_->getLastBytesProcessed());
|
||||
socketRecvBuffer_->drain(headerProcessor_->getLastBytesProcessed());
|
||||
bodyConsumed_ = 0;
|
||||
if(setupResponseRecv() < 0) {
|
||||
A2_LOG_INFO("Request path is invaild. Ignore the request body.");
|
||||
|
@ -175,7 +175,7 @@ bool HttpServer::receiveRequest()
|
|||
}
|
||||
return true;
|
||||
} else {
|
||||
socketRecvBuffer_->shiftBuffer(headerProcessor_->getLastBytesProcessed());
|
||||
socketRecvBuffer_->drain(headerProcessor_->getLastBytesProcessed());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ bool HttpServer::receiveBody()
|
|||
if(lastBody_) {
|
||||
lastBody_->writeData(socketRecvBuffer_->getBuffer(), length, 0);
|
||||
}
|
||||
socketRecvBuffer_->shiftBuffer(length);
|
||||
socketRecvBuffer_->drain(length);
|
||||
bodyConsumed_ += length;
|
||||
return lastContentLength_ == bodyConsumed_;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ bool HttpSkipResponseCommand::executeInternal()
|
|||
getSocketRecvBuffer()->getBufferLength());
|
||||
bufSize = streamFilter_->getBytesProcessed();
|
||||
}
|
||||
getSocketRecvBuffer()->shiftBuffer(bufSize);
|
||||
getSocketRecvBuffer()->drain(bufSize);
|
||||
}
|
||||
if(totalLength_ != 0 && eof) {
|
||||
throw DL_RETRY_EX(EX_GOT_EOF);
|
||||
|
|
|
@ -39,17 +39,11 @@
|
|||
|
||||
#include "SocketCore.h"
|
||||
#include "LogFactory.h"
|
||||
#include "a2functional.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
SocketRecvBuffer::SocketRecvBuffer
|
||||
(std::shared_ptr<SocketCore> socket,
|
||||
size_t capacity)
|
||||
: socket_(std::move(socket)),
|
||||
capacity_(capacity),
|
||||
buf_(make_unique<unsigned char[]>(capacity_)),
|
||||
bufLen_(0)
|
||||
SocketRecvBuffer::SocketRecvBuffer(std::shared_ptr<SocketCore> socket)
|
||||
: socket_(std::move(socket)), pos_(buf_.data()), last_(pos_)
|
||||
{}
|
||||
|
||||
SocketRecvBuffer::~SocketRecvBuffer()
|
||||
|
@ -57,21 +51,28 @@ SocketRecvBuffer::~SocketRecvBuffer()
|
|||
|
||||
ssize_t SocketRecvBuffer::recv()
|
||||
{
|
||||
size_t len = capacity_ - bufLen_;
|
||||
if(len > 0) {
|
||||
socket_->readData(buf_.get() + bufLen_, len);
|
||||
bufLen_ += len;
|
||||
} else {
|
||||
size_t n = std::end(buf_) - last_;
|
||||
if (n == 0) {
|
||||
A2_LOG_DEBUG("Buffer full");
|
||||
return 0;
|
||||
}
|
||||
return len;
|
||||
socket_->readData(last_, n);
|
||||
last_ += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
void SocketRecvBuffer::shiftBuffer(size_t offset)
|
||||
void SocketRecvBuffer::drain(size_t n)
|
||||
{
|
||||
assert(offset <= bufLen_);
|
||||
memmove(buf_.get(), buf_.get() + offset, bufLen_ - offset);
|
||||
bufLen_ -= offset;
|
||||
assert(pos_ + n <= last_);
|
||||
pos_ += n;
|
||||
if (pos_ == last_) {
|
||||
truncateBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void SocketRecvBuffer::truncateBuffer()
|
||||
{
|
||||
pos_ = last_ = buf_.data();
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "common.h"
|
||||
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -45,21 +46,17 @@ class SocketCore;
|
|||
|
||||
class SocketRecvBuffer {
|
||||
public:
|
||||
SocketRecvBuffer
|
||||
(std::shared_ptr<SocketCore> socket,
|
||||
size_t capacity = 16*1024);
|
||||
SocketRecvBuffer(std::shared_ptr<SocketCore> socket);
|
||||
~SocketRecvBuffer();
|
||||
// Reads data from socket as much as capacity allows. Returns the
|
||||
// number of bytes read.
|
||||
ssize_t recv();
|
||||
// Shifts buffer by offset bytes. offset must satisfy offset <=
|
||||
// getBufferLength().
|
||||
void shiftBuffer(size_t offset);
|
||||
// Truncates the contents of buffer to 0.
|
||||
void clearBuffer()
|
||||
{
|
||||
bufLen_ = 0;
|
||||
}
|
||||
void truncateBuffer();
|
||||
// Drains first n bytes of data from buffer. It is an programmer's
|
||||
// responsibility to ensure that n is smaller or equal to the
|
||||
// buffered data.
|
||||
void drain(size_t n);
|
||||
|
||||
const std::shared_ptr<SocketCore>& getSocket() const
|
||||
{
|
||||
|
@ -68,25 +65,24 @@ public:
|
|||
|
||||
const unsigned char* getBuffer() const
|
||||
{
|
||||
return buf_.get();
|
||||
return pos_;
|
||||
}
|
||||
|
||||
size_t getBufferLength() const
|
||||
{
|
||||
return bufLen_;
|
||||
return last_ - pos_;
|
||||
}
|
||||
|
||||
bool bufferEmpty() const
|
||||
{
|
||||
return bufLen_ == 0;
|
||||
return pos_ == last_;
|
||||
}
|
||||
|
||||
void pushBuffer(const unsigned char* data, size_t len);
|
||||
private:
|
||||
std::array<unsigned char, 16384> buf_;
|
||||
std::shared_ptr<SocketCore> socket_;
|
||||
size_t capacity_;
|
||||
std::unique_ptr<unsigned char[]> buf_;
|
||||
size_t bufLen_;
|
||||
unsigned char *pos_;
|
||||
unsigned char *last_;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
Loading…
Reference in New Issue