8 struct memblock_list *next;
13 struct memblock_list *blocks, *blocks_tail;
22 struct memblockq* memblockq_new(size_t maxlength, size_t base, size_t prebuf) {
24 assert(maxlength && base);
26 bq = malloc(sizeof(struct memblockq));
28 bq->blocks = bq->blocks_tail = 0;
32 bq->maxlength = ((maxlength+base-1)/base)*base;
33 bq->prebuf = prebuf == (size_t) -1 ? bq->maxlength/2 : prebuf;
35 if (bq->prebuf > bq->maxlength)
36 bq->prebuf = bq->maxlength;
38 assert(bq->maxlength >= base);
43 void memblockq_free(struct memblockq* bq) {
44 struct memblock_list *l;
47 while ((l = bq->blocks)) {
49 memblock_unref(l->chunk.memblock);
56 void memblockq_push(struct memblockq* bq, struct memchunk *chunk, size_t delta) {
57 struct memblock_list *q;
58 assert(bq && chunk && chunk->memblock && chunk->length);
60 q = malloc(sizeof(struct memblock_list));
64 memblock_ref(q->chunk.memblock);
65 assert(q->chunk.index+q->chunk.length <= q->chunk.memblock->length);
69 bq->blocks_tail->next = q;
76 bq->total_length += chunk->length;
78 memblockq_shorten(bq, bq->maxlength);
81 int memblockq_peek(struct memblockq* bq, struct memchunk *chunk) {
84 if (!bq->blocks || bq->total_length < bq->prebuf)
89 *chunk = bq->blocks->chunk;
90 memblock_ref(chunk->memblock);
94 int memblockq_pop(struct memblockq* bq, struct memchunk *chunk) {
95 struct memblock_list *q;
99 if (!bq->blocks || bq->total_length < bq->prebuf)
105 bq->blocks = bq->blocks->next;
110 bq->total_length -= chunk->length;
116 void memblockq_drop(struct memblockq *bq, size_t length) {
121 assert(bq->blocks && bq->total_length >= length);
123 if (l > bq->blocks->chunk.length)
124 l = bq->blocks->chunk.length;
126 bq->blocks->chunk.index += l;
127 bq->blocks->chunk.length -= l;
128 bq->total_length -= l;
130 if (bq->blocks->chunk.length == 0) {
131 struct memblock_list *q;
134 bq->blocks = bq->blocks->next;
135 if (bq->blocks == NULL)
136 bq->blocks_tail = NULL;
137 memblock_unref(q->chunk.memblock);
147 void memblockq_shorten(struct memblockq *bq, size_t length) {
151 if (bq->total_length <= length)
154 fprintf(stderr, "Warning! memblockq_shorten()\n");
156 l = bq->total_length - length;
160 memblockq_drop(bq, l);
164 void memblockq_empty(struct memblockq *bq) {
166 memblockq_shorten(bq, 0);
169 int memblockq_is_readable(struct memblockq *bq) {
172 return bq->total_length >= bq->prebuf;
175 int memblockq_is_writable(struct memblockq *bq, size_t length) {
178 assert(length <= bq->maxlength);
179 return bq->total_length + length <= bq->maxlength;