memchunk: Refactor
This commit is contained in:
parent
2349a03882
commit
7baf6f781e
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -38,21 +39,20 @@ namespace nghttp2 {
|
||||||
|
|
||||||
template <size_t N> struct Memchunk {
|
template <size_t N> struct Memchunk {
|
||||||
Memchunk(std::unique_ptr<Memchunk> next_chunk)
|
Memchunk(std::unique_ptr<Memchunk> next_chunk)
|
||||||
: knext(std::move(next_chunk)), kprev(nullptr), next(nullptr), pos(begin),
|
: pos(std::begin(buf)), last(pos), knext(std::move(next_chunk)),
|
||||||
last(begin), end(begin + N) {
|
kprev(nullptr), next(nullptr) {
|
||||||
if (knext) {
|
if (knext) {
|
||||||
knext->kprev = this;
|
knext->kprev = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t len() const { return last - pos; }
|
size_t len() const { return last - pos; }
|
||||||
size_t left() const { return end - last; }
|
size_t left() const { return std::end(buf) - last; }
|
||||||
void reset() { pos = last = begin; }
|
void reset() { pos = last = std::begin(buf); }
|
||||||
|
std::array<uint8_t, N> buf;
|
||||||
|
uint8_t *pos, *last;
|
||||||
std::unique_ptr<Memchunk> knext;
|
std::unique_ptr<Memchunk> knext;
|
||||||
Memchunk *kprev;
|
Memchunk *kprev;
|
||||||
Memchunk *next;
|
Memchunk *next;
|
||||||
uint8_t *pos, *last;
|
|
||||||
uint8_t *end;
|
|
||||||
uint8_t begin[N];
|
|
||||||
static const size_t size = N;
|
static const size_t size = N;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,11 +106,6 @@ template <typename T> struct Pool {
|
||||||
size_t poolsize;
|
size_t poolsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void *cpymem(void *dest, const void *src, size_t count) {
|
|
||||||
memcpy(dest, src, count);
|
|
||||||
return reinterpret_cast<uint8_t *>(dest) + count;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Memchunk> struct Memchunks {
|
template <typename Memchunk> struct Memchunks {
|
||||||
Memchunks(Pool<Memchunk> *pool)
|
Memchunks(Pool<Memchunk> *pool)
|
||||||
: pool(pool), head(nullptr), tail(nullptr), len(0) {}
|
: pool(pool), head(nullptr), tail(nullptr), len(0) {}
|
||||||
|
@ -124,54 +119,53 @@ template <typename Memchunk> struct Memchunks {
|
||||||
m = next;
|
m = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t append(const void *data, size_t count) {
|
size_t append(const void *src, size_t count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto p = reinterpret_cast<const uint8_t *>(data);
|
auto first = static_cast<const uint8_t *>(src);
|
||||||
|
auto last = first + count;
|
||||||
|
|
||||||
if (!tail) {
|
if (!tail) {
|
||||||
head = tail = pool->get();
|
head = tail = pool->get();
|
||||||
}
|
}
|
||||||
auto all = count;
|
|
||||||
|
|
||||||
while (count > 0) {
|
for (;;) {
|
||||||
auto n = std::min(count, tail->left());
|
auto n = std::min(static_cast<size_t>(last - first), tail->left());
|
||||||
tail->last = reinterpret_cast<uint8_t *>(cpymem(tail->last, p, n));
|
tail->last = std::copy_n(first, n, tail->last);
|
||||||
p += n;
|
first += n;
|
||||||
count -= n;
|
|
||||||
len += n;
|
len += n;
|
||||||
if (count == 0) {
|
if (first == last) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tail->next = pool->get();
|
tail->next = pool->get();
|
||||||
|
|
||||||
assert(tail != tail->next);
|
|
||||||
tail = tail->next;
|
tail = tail->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return all;
|
return count;
|
||||||
}
|
}
|
||||||
template <size_t N> size_t append(const char (&s)[N]) {
|
template <size_t N> size_t append(const char (&s)[N]) {
|
||||||
return append(s, N - 1);
|
return append(s, N - 1);
|
||||||
}
|
}
|
||||||
size_t remove(void *data, size_t count) {
|
size_t remove(void *dest, size_t count) {
|
||||||
if (!tail || count == 0) {
|
if (!tail || count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto ndata = count;
|
|
||||||
|
auto first = static_cast<uint8_t *>(dest);
|
||||||
|
auto last = first + count;
|
||||||
|
|
||||||
auto m = head;
|
auto m = head;
|
||||||
|
|
||||||
while (m) {
|
while (m) {
|
||||||
auto next = m->next;
|
auto next = m->next;
|
||||||
auto n = std::min(count, m->len());
|
auto n = std::min(static_cast<size_t>(last - first), m->len());
|
||||||
|
|
||||||
assert(m->len());
|
assert(m->len());
|
||||||
data = cpymem(data, m->pos, n);
|
first = std::copy_n(m->pos, n, first);
|
||||||
m->pos += n;
|
m->pos += n;
|
||||||
count -= n;
|
|
||||||
len -= n;
|
len -= n;
|
||||||
if (m->len() > 0) {
|
if (m->len() > 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -184,7 +178,7 @@ template <typename Memchunk> struct Memchunks {
|
||||||
tail = nullptr;
|
tail = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndata - count;
|
return first - static_cast<uint8_t *>(dest);
|
||||||
}
|
}
|
||||||
size_t drain(size_t count) {
|
size_t drain(size_t count) {
|
||||||
auto ndata = count;
|
auto ndata = count;
|
||||||
|
|
|
@ -159,12 +159,12 @@ void test_memchunks_riovec(void) {
|
||||||
auto m = chunks.head;
|
auto m = chunks.head;
|
||||||
|
|
||||||
CU_ASSERT(2 == iovcnt);
|
CU_ASSERT(2 == iovcnt);
|
||||||
CU_ASSERT(m->begin == iov[0].iov_base);
|
CU_ASSERT(m->buf.data() == iov[0].iov_base);
|
||||||
CU_ASSERT(m->len() == iov[0].iov_len);
|
CU_ASSERT(m->len() == iov[0].iov_len);
|
||||||
|
|
||||||
m = m->next;
|
m = m->next;
|
||||||
|
|
||||||
CU_ASSERT(m->begin == iov[1].iov_base);
|
CU_ASSERT(m->buf.data() == iov[1].iov_base);
|
||||||
CU_ASSERT(m->len() == iov[1].iov_len);
|
CU_ASSERT(m->len() == iov[1].iov_len);
|
||||||
|
|
||||||
chunks.drain(2 * 16);
|
chunks.drain(2 * 16);
|
||||||
|
@ -174,7 +174,7 @@ void test_memchunks_riovec(void) {
|
||||||
CU_ASSERT(1 == iovcnt);
|
CU_ASSERT(1 == iovcnt);
|
||||||
|
|
||||||
m = chunks.head;
|
m = chunks.head;
|
||||||
CU_ASSERT(m->begin == iov[0].iov_base);
|
CU_ASSERT(m->buf.data() == iov[0].iov_base);
|
||||||
CU_ASSERT(m->len() == iov[0].iov_len);
|
CU_ASSERT(m->len() == iov[0].iov_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue