[core] reuse chunkqueue_compact_mem*()
parent
9c25581d6f
commit
e18da93e44
32
src/chunk.c
32
src/chunk.c
|
@ -758,27 +758,40 @@ static void chunkqueue_remove_empty_chunks(chunkqueue *cq) {
|
|||
}
|
||||
}
|
||||
|
||||
void chunkqueue_compact_mem_offset(chunkqueue * const cq) {
|
||||
chunk * const restrict c = cq->first;
|
||||
if (0 == c->offset) return;
|
||||
if (c->type != MEM_CHUNK) return; /*(should not happen)*/
|
||||
|
||||
buffer * const restrict b = c->mem;
|
||||
size_t len = chunk_buffer_string_length(b) - c->offset;
|
||||
memmove(b->ptr, b->ptr+c->offset, len);
|
||||
c->offset = 0;
|
||||
buffer_string_set_length(b, len);
|
||||
}
|
||||
|
||||
void chunkqueue_compact_mem(chunkqueue *cq, size_t clen) {
|
||||
/* caller must guarantee that chunks in chunkqueue are MEM_CHUNK,
|
||||
* which is currently always true when reading input from client */
|
||||
chunk *c = cq->first;
|
||||
buffer *b = c->mem;
|
||||
size_t len = buffer_string_length(b) - c->offset;
|
||||
size_t len = chunk_buffer_string_length(b) - c->offset;
|
||||
if (len <= clen) return;
|
||||
if (b->size > clen) {
|
||||
if (0 != c->offset) {
|
||||
memmove(b->ptr, b->ptr+c->offset, len);
|
||||
buffer_string_set_length(b, len);
|
||||
c->offset = 0;
|
||||
}
|
||||
if (chunk_buffer_string_space(b) < clen - len)
|
||||
chunkqueue_compact_mem_offset(cq);
|
||||
}
|
||||
else {
|
||||
b = chunkqueue_prepend_buffer_open_sz(cq, clen + 8192);
|
||||
b = chunkqueue_prepend_buffer_open_sz(cq, clen+1);
|
||||
buffer_append_string_len(b, c->mem->ptr + c->offset, len);
|
||||
cq->first->next = c->next;
|
||||
if (NULL == c->next) cq->last = cq->first;
|
||||
chunk_release(c);
|
||||
c = cq->first;
|
||||
}
|
||||
|
||||
for (chunk *fc = c; ((clen -= len) && (c = fc->next)); ) {
|
||||
len = buffer_string_length(c->mem) - c->offset;
|
||||
len = chunk_buffer_string_length(c->mem) - c->offset;
|
||||
if (len > clen) {
|
||||
buffer_append_string_len(b, c->mem->ptr + c->offset, clen);
|
||||
c->offset += clen;
|
||||
|
@ -893,7 +906,8 @@ chunkqueue_peek_data (chunkqueue * const cq,
|
|||
switch (c->type) {
|
||||
case MEM_CHUNK:
|
||||
{
|
||||
uint32_t have = buffer_string_length(c->mem) - (uint32_t)c->offset;
|
||||
uint32_t have =
|
||||
chunk_buffer_string_length(c->mem) - (uint32_t)c->offset;
|
||||
if (have > space)
|
||||
have = space;
|
||||
if (*dlen)
|
||||
|
|
|
@ -119,6 +119,7 @@ int chunkqueue_steal_with_tempfiles(chunkqueue * restrict dest, chunkqueue * res
|
|||
|
||||
int chunkqueue_open_file_chunk(chunkqueue * restrict cq, struct log_error_st * const restrict errh);
|
||||
|
||||
void chunkqueue_compact_mem_offset(chunkqueue *cq);
|
||||
void chunkqueue_compact_mem(chunkqueue *cq, size_t clen);
|
||||
|
||||
void chunkqueue_small_resp_optim (chunkqueue * restrict cq);
|
||||
|
|
|
@ -704,10 +704,8 @@ static int connection_handle_read_state(connection * const con) {
|
|||
if (NULL == c) continue;
|
||||
clen = buffer_string_length(c->mem) - c->offset;
|
||||
if (0 == clen) continue;
|
||||
if (c->offset > USHRT_MAX) { /*(highly unlikely)*/
|
||||
chunkqueue_compact_mem(cq, clen);
|
||||
c = cq->first; /*(reload c after chunkqueue_compact_mem())*/
|
||||
}
|
||||
if (c->offset > USHRT_MAX) /*(highly unlikely)*/
|
||||
chunkqueue_compact_mem_offset(cq);
|
||||
|
||||
hoff[0] = 1; /* number of lines */
|
||||
hoff[1] = (unsigned short)c->offset; /* base offset for all lines */
|
||||
|
@ -1659,20 +1657,14 @@ connection_handle_read_post_cq_compact (chunkqueue * const cq)
|
|||
{
|
||||
/* combine first mem chunk with next non-empty mem chunk
|
||||
* (loop if next chunk is empty) */
|
||||
chunk *c;
|
||||
while (NULL != (c = cq->first) && NULL != c->next) {
|
||||
buffer *mem = c->next->mem;
|
||||
off_t offset = c->next->offset;
|
||||
size_t blen = buffer_string_length(mem) - (size_t)offset;
|
||||
force_assert(c->type == MEM_CHUNK);
|
||||
force_assert(c->next->type == MEM_CHUNK);
|
||||
buffer_append_string_len(c->mem, mem->ptr+offset, blen);
|
||||
c->next->offset = c->offset;
|
||||
c->next->mem = c->mem;
|
||||
c->mem = mem;
|
||||
c->offset = offset + (off_t)blen;
|
||||
chunkqueue_remove_finished_chunks(cq);
|
||||
if (0 != blen) return 1;
|
||||
chunk *c = cq->first;
|
||||
if (NULL == c) return 0;
|
||||
const uint32_t mlen = buffer_string_length(c->mem) - (size_t)c->offset;
|
||||
while ((c = c->next)) {
|
||||
const uint32_t blen = buffer_string_length(c->mem) - (size_t)c->offset;
|
||||
if (0 == blen) continue;
|
||||
chunkqueue_compact_mem(cq, mlen + blen);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
38
src/h2.c
38
src/h2.c
|
@ -896,42 +896,8 @@ h2_frame_cq_compact (chunkqueue * const cq, uint32_t len)
|
|||
/*assert(cq->first != cq->last);*//*(multiple chunks)*/
|
||||
/* caller must guarantee that chunks in chunkqueue are all MEM_CHUNK */
|
||||
|
||||
/* move data to beginning of buffer if offset is large or data is short */
|
||||
chunk *c = cq->first;
|
||||
uint32_t mlen = buffer_string_length(c->mem);
|
||||
if (mlen < c->offset) {
|
||||
memmove(c->mem->ptr, c->mem->ptr + c->offset, mlen);
|
||||
buffer_string_set_length(c->mem, mlen);
|
||||
c->offset = 0;
|
||||
}
|
||||
|
||||
/* combine first mem chunk with next non-empty mem chunks up to len
|
||||
* (loop if next chunk is empty) */
|
||||
/* (modified from connection_handle_read_post_cq_compact()) */
|
||||
uint32_t clen = mlen;
|
||||
do {
|
||||
buffer * const mem = c->next->mem;
|
||||
const off_t offset = c->next->offset;
|
||||
mlen = buffer_string_length(mem) - (uint32_t)offset;
|
||||
force_assert(c->type == MEM_CHUNK);
|
||||
force_assert(c->next->type == MEM_CHUNK);
|
||||
if (mlen > clen - len) {
|
||||
mlen = clen - len;
|
||||
buffer_append_string_len(c->mem, mem->ptr+offset, mlen);
|
||||
c->next->offset += mlen;
|
||||
return len;
|
||||
}
|
||||
|
||||
buffer_append_string_len(c->mem, mem->ptr+offset, mlen);
|
||||
clen += mlen;
|
||||
/*(swap first and second chunk, then remove first chunk)*/
|
||||
c->next->offset = c->offset;
|
||||
c->next->mem = c->mem;
|
||||
c->mem = mem;
|
||||
c->offset = offset + (off_t)mlen;
|
||||
chunkqueue_remove_finished_chunks(cq);
|
||||
} while ((c = cq->first)); /*(need to re-read cq->first)*/
|
||||
return clen;
|
||||
chunkqueue_compact_mem(cq, len);
|
||||
return buffer_string_length(cq->first->mem) - (uint32_t)cq->first->offset;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue