piece-chain

Research & implementation of a Piece Chain
git clone git://src.gearsix.net/piece-chain.git
Log | Files | Refs | Atom | README

commit 003fd961221b10fd75960257c508b107e252bb27
parent 0cec6d691981dbb10d2d0967dd0e3302eda34586
Author: gearsix <gearsix@tuta.io>
Date:   Sat,  9 Jul 2022 12:43:13 +0100

added buffree; fixed all memory leaks.

Diffstat:
Mbuf.c | 69++++++++++++++++++++++++++++++++++++++++-----------------------------
Mbuf.h | 4+++-
Mtest.c | 9+++++++--
3 files changed, 50 insertions(+), 32 deletions(-)

diff --git a/buf.c b/buf.c @@ -5,43 +5,44 @@ #include <stdlib.h> #include <string.h> -static const size_t blksiz = BUFSIZ/sizeof(Piece); -static Piece **nextp = NULL; +static Piece *pieceblk = NULL; /* block of all pieces */ +static Piece **freeblk = NULL; /* ptr block to all free'd `pieceblk` items */ -static size_t pfree(Piece *p) +static void pclean() +{ + free(freeblk); + free(pieceblk); +} + +static Piece *pfree(Piece *p) { - static Piece **freeblk = NULL; static size_t nblk = 0, nfree = 0; + static const size_t blksiz = BUFSIZ/sizeof(Piece *); - if (!p) { - if (!nextp && nfree > 0) - nextp = &freeblk[--nfree]; - return nfree; - } + if (!p) return (nfree == 0) ? NULL : freeblk[--nfree]; if (nfree + 1 > blksiz * nblk) freeblk = realloc(freeblk, (++nblk * blksiz) * sizeof(Piece *)); if (!freeblk) { perror("failed to allocate freeblk"); exit(1); } - freeblk[nfree++] = p; - nextp = &freeblk[nfree - 1]; - return nfree; + return freeblk[nfree++] = p; } static Piece *palloc() { Piece *p; - static Piece *pieceblk = NULL; - static size_t nblk = 0, npieces = 0; + + static size_t nblk = 0, nalloc = 0; + static const size_t blksiz = BUFSIZ/sizeof(Piece); - if (pfree(NULL) > 0) { - p = *nextp; - nextp = NULL; - } else { - if (npieces + 1 > blksiz * nblk) + static int hook = 0; + if (hook == 0) { atexit(pclean); hook = 1; } + + if ( !(p = pfree(NULL)) ) { + if (nalloc + 1 > blksiz * nblk) pieceblk = realloc(pieceblk, (++nblk * blksiz) * sizeof(Piece)); if (!pieceblk) { perror("failed to allocate pieceblk"); exit(1); } - p = &pieceblk[npieces++]; + p = &pieceblk[nalloc++]; } return memset(p, 0, sizeof(Piece)); @@ -65,23 +66,33 @@ static Piece *psplit(Piece *p, long int offset) return p; } -struct Buf *bufinit(FILE *f) +struct Buf *bufinit(FILE *read, FILE *append) { Buf *b = calloc(1, sizeof(Buf)); - b->append = tmpfile(); + if (!read || !append) return NULL; + + b->read = read; + b->append = append; + b->tail = b->pos = b->head = palloc(); - - if (f) { - b->read =f; - b->pos->f = b->read; - fseek(b->read, 0, SEEK_END); - b->size = b->pos->len = ftell(b->read); - } + b->pos->f = b->read; + fseek(b->read, 0, SEEK_END); + b->size = b->pos->len = ftell(b->read); return b; } +void buffree(Buf *b) +{ + Piece *p = b->tail->next; + while (p) { + pfree(p->prev); + p = p->next; + } + free(b); +} + Piece *bufidx(Buf *b, size_t pos) { size_t idx = b->idx, offset; diff --git a/buf.h b/buf.h @@ -15,7 +15,9 @@ typedef struct Buf { struct Piece *tail, *pos, *head; } Buf; -Buf *bufinit(FILE *f); +Buf *bufinit(FILE *read, FILE *append); + +void buffree(Buf *b); Piece *bufidx(Buf *b, size_t pos); diff --git a/test.c b/test.c @@ -1,5 +1,6 @@ #include "buf.h" #include <stdio.h> +#include <stdlib.h> #include <assert.h> #include <string.h> @@ -9,7 +10,7 @@ #define OUTBUF "hey buddy!" /* tests will aim to change INBUF to this */ Buf *b; -FILE *in, *out; +FILE *in, *tmp, *out; void setup() { @@ -17,6 +18,8 @@ void setup() if (ferror(in)) perror("fopen in.txt"); fputs(INBUF, in); + tmp = tmpfile(); + out = fopen(OUTFILE, "w+b"); if (ferror(in)) perror("fopen out.txt"); @@ -25,8 +28,10 @@ void setup() void setdown() { + buffree(b); fclose(out); fclose(in); + fclose(tmp); } void print() @@ -52,7 +57,7 @@ void test_bufinit() { Piece *p; - b = bufinit(in); + b = bufinit(in, tmp); assert(b->read); assert(b->append);