ring

dynamic ring array
git clone https://noulin.net/git/ring.git
Log | Files | Refs | LICENSE

commit 1bc992509313cc04e3c6e6e0bc5431ef03ac6481
parent b84035d233b26c97093caedcb40cf70c0d81380b
Author: Remy Noulin <loader2x@gmail.com>
Date:   Sun, 20 May 2018 10:36:56 +0200

ring buffer

cRing.c         | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cRing.h         | 110 +++++++++++++++++++++++
cRingInternal.h |   4 +
package.yml     |  15 ++++
ring.c          |  59 ++++++++++++
5 files changed, 459 insertions(+)

Diffstat:
AcRing.c | 271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AcRing.h | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AcRingInternal.h | 4++++
Apackage.yml | 15+++++++++++++++
Aring.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 459 insertions(+), 0 deletions(-)

diff --git a/cRing.c b/cRing.c @@ -0,0 +1,271 @@ +// +// +// + +#include "libsheepyObject.h" +#include "cRing.h" +#include "cRingInternal.h" + +#define internal static + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +void initiateRing(ringt *self); +void initiateAllocateRing(ringt **self); +void finalizeRing(void); +internal void freeRing(ringt *self); +internal void terminateRing(ringt **self); +internal char* toStringRing(ringt *self); +internal ringt* duplicateRing(ringt *self); +internal void smashRing(ringt **self); +internal void finishRing(ringt **self); +internal void setSizeRing(ringt *self, size_t size); +internal bool rIsEmptyRing(smallArrayt *self); +internal bool isFullRing(ringt *self); +internal i64 countRing(ringt *self); +internal i64 maxCountRing(ringt *self); +internal baset* lastRing(ringt *self); +internal baset* firstRing(ringt *self); +internal baset* getFromRing(ringt *self, intmax_t index); + +// replace parent functions +internal smallArrayt* pushRing(smallArrayt *self, baset *value); +internal baset* popRing(smallArrayt *self); +internal smallArrayt* prependRing(smallArrayt *self, baset *value); +internal baset* dequeueRing(smallArrayt *self); + +void initiateRing(ringt *self) { + + self->type = "ring"; + + if (!ringF) { + ringF = malloc(sizeof(ringFunctionst)); + registerMethodsSmallArray((smallArrayFunctionst *) ringF); + + // SAME AS PARENT + /* ringF->free = freeRing; */ + /* ringF->terminate = terminateRing; */ + /* ringF->toString = toStringRing; */ + ringF->duplicate = duplicateRing; + /* ringF->smash = smashRing; */ + /* ringF->finish = finishRing; */ + + ringF->setSize = setSizeRing; + ringF->isFull = isFullRing; + ringF->count = countRing; + ringF->maxCount = maxCountRing; + ringF->last = lastRing; + ringF->first = firstRing; + ringF->send = pushRing; + ringF->recv = dequeueRing; + ringF->getFrom = getFromRing; + + // save and replace parent class functions + ringF->parentIsEmpty= ringF->isEmpty; + ringF->parentPush = ringF->push; + ringF->parentPop = ringF->pop; + ringF->parentPrepend= ringF->prepend; + ringF->parentDequeue= ringF->dequeue; + + ringF->isEmpty = rIsEmptyRing; + ringF->push = pushRing; + ringF->pop = popRing; + ringF->prepend = prependRing; + ringF->dequeue = dequeueRing; + + } + self->f = ringF; + + self->a = NULL; + self->last = self->head = 0; + self->isEmpty = true; +} + +void initiateAllocateRing(ringt **self) { + + if (self) { + (*self) = malloc(sizeof(ringt)); + if (*self) { + initiateRing(*self); + } + } +} + +void finalizeRing(void) { + + if (ringF) { + free(ringF); + ringF = NULL; + } +} + +ringt* allocRing(void) { + ringt *r; + + initiateAllocateRing(&r); + return(r); +} + + +// SAME AS PARENT +/* internal void freeRing(ringt *self) { */ +/* */ +/* // */ +/* return; */ +/* } */ +/* */ +/* internal void terminateRing(ringt **self) { */ +/* */ +/* (*self)->f->free(*self); */ +/* free(*self); */ +/* *self = NULL; */ +/* } */ +/* */ +/* */ +/* internal char* toStringRing(ringt *self) { */ +/* */ +/* return(strdup("- class template")); */ +/* } */ + +internal ringt* duplicateRing(ringt *self) { + + createAllocateRing(dup); + forEachSArray(self->a, o) + if (o) + sArrayPushTiny(&(dup->a), sDuplicateTiny(o)); + dup->last = self->last; + dup->head = self->head; + dup->isEmpty = self->isEmpty; + return(dup); +} + +// SAME AS PARENT +/* internal void smashRing(ringt **self) { */ +/* */ +/* free(*self); */ +/* *self = NULL; */ +/* } */ +/* */ +/* internal void finishRing(ringt **self) { */ +/* */ +/* free(*self); */ +/* *self = NULL; */ +/* } */ + +internal void setSizeRing(ringt *self, size_t size) { + range(i, size) { + self->f->parentPush( cAr(self), NULL); + } +} + +internal bool rIsEmptyRing(smallArrayt *self) { + return ((ringt *)self)->isEmpty; +} + +internal bool isFullRing(ringt *self) { + + if (self->isEmpty) return false; + + return (((self->last+1) % lenO(cAr(self))) == self->head); +} + +internal i64 countRing(ringt *self) { + + if (self->isEmpty) return 0; + if (self->last >= self->head) return (self->last - self->head +1); + else return (lenO(cAr(self)) - self->head + self->last +1); +} + +internal i64 maxCountRing(ringt *self) { + return lenO(cAr(self)); +} + +internal smallArrayt* pushRing(smallArrayt *self, baset *value) { + + cast(ringt *, rg, self); + if (rg->f->isFull(rg)) return self; + + if (rg->isEmpty) { + rg->isEmpty = false; + } + else { + rg->last++; + rg->last %= lenO(cAr(self)); + } + self->f->set(self, rg->last, value); + return self; +} + +internal baset* popRing(smallArrayt *self) { + + cast(ringt *, rg, self); + + baset *r = self->f->get(self, rg->last); + + if (!rg->isEmpty && (rg->last == rg->head)) + rg->isEmpty = true; + else if (!rg->isEmpty && (rg->last != rg->head)) + rg->last--; + if (rg->last < 0) + rg->last += lenO(cAr(self)); + rg->last %= lenO(cAr(self)); + return r; +} + +internal smallArrayt* prependRing(smallArrayt *self, baset *value) { + + cast(ringt *, rg, self); + + if (rg->f->isFull(rg)) return self; + + if (rg->f->isEmpty) { + rg->f->isEmpty = false; + } + else { + rg->head--; + if (rg->head < 0) { + rg->head += lenO(cAr(self)); + } + rg->head %= lenO(cAr(self)); + } + + self->f->set(self, rg->head, value); + return self; +} + +internal baset* dequeueRing(smallArrayt *self) { + + cast(ringt *, rg, self); + + baset *r = self->f->get(self, rg->head); + + if (!rg->isEmpty && (rg->last == rg->head)) { + rg->isEmpty = true; + } + else if (!rg->isEmpty && (rg->last != rg->head)) { + rg->head++; + rg->head %= lenO(cAr(self)); + } + + return r; +} + +internal baset* lastRing(ringt *self) { + if (self->isEmpty) return NULL; + return self->f->get( cAr(self), self->last); +} + +internal baset* firstRing(ringt *self) { + if (self->isEmpty) return NULL; + return self->f->get( cAr(self), self->head); +} + +internal baset* getFromRing(ringt *self, intmax_t index) { + + if (self->isEmpty) return NULL; + + baset *r = self->f->get( cAr(self), (index + self->head) % lenO(cAr(self))); + return r; +} diff --git a/cRing.h b/cRing.h @@ -0,0 +1,110 @@ +#pragma once +// Class ring, inherit from smallArrayt +// cast ringt with cAr() macro when calling parent functions + +#include "libsheepyObject.h" +typedef struct ring ringt; + +typedef void (*freeRingFt) (ringt *self); +typedef void (*terminateRingFt) (ringt **self); +typedef char* (*toStringRingFt) (ringt *self); +typedef ringt* (*duplicateRingFt) (ringt *self); +typedef void (*smashRingFt) (ringt **self); + +/** + * free container + */ +typedef void (*finishRingFt) (ringt **self); + +typedef void (*setSizeRingFt) (ringt *self, size_t size); +typedef bool (*isFullRingFt) (ringt *self); +typedef i64 (*countRingFt) (ringt *self); +typedef i64 (*maxCountRingFt) (ringt *self); +typedef baset* (*lastRingFt) (ringt *self); +typedef baset* (*firstRingFt) (ringt *self); +typedef baset* (*getFromRingFt) (ringt *self, intmax_t index); + +/** + * class functions + * allocated once for all objects + * + * freed with finalizeRing or finalizeLibsheepy + */ + +#define RINGFUNCTIONST \ + SMALLARRAYFUNCTIONST; \ + setSizeRingFt setSize;\ + isFullRingFt isFull;\ + countRingFt count;\ + maxCountRingFt maxCount;\ + lastRingFt last;\ + firstRingFt first;\ + pushSmallArrayFt send;\ + dequeueSmallArrayFt recv;\ + getFromRingFt getFrom;\ + /* TODO getHead, ring get should work like staticArrayRef */\ + /* saved parent class functions */\ + isEmptySmallArrayFt parentIsEmpty;\ + pushSmallArrayFt parentPush;\ + popSmallArrayFt parentPop;\ + prependSmallArrayFt parentPrepend;\ + dequeueSmallArrayFt parentDequeue\ + /* TODO fromSmallArray */\ + /* TODO create container */ + +typedef struct { + freeRingFt free; + terminateRingFt terminate; + toStringRingFt toString; + duplicateRingFt duplicate; + smashRingFt smash; + finishRingFt finish; + + RINGFUNCTIONST; +} ringFunctionst; + +/** + * class + */ +struct ring { + const char *type; + ringFunctionst *f; + + // internal + sArrayt *a; + i64 last; + i64 head; + bool isEmpty; +}; + +// ring + +#define createRing(obj) ringt obj; initiateRing(&obj) +#define createAllocateRing(obj) ringt *obj; initiateAllocateRing(&obj) + +void initiateRing(ringt *self); +void initiateAllocateRing(ringt **self); +void finalizeRing(void); + +ringt* allocRing(/*INIT DATA */); + +// Generics +#define setSizeO(self, size) (self)->f->setSize(self, size) +#define setSizeG setSizeO + +#define isFullO(self) (self)->f->isFull(self) +#define isFullG isFullO + +#define rCountO(self) (self)->f->count(self) +#define rCountG rCountO + +#define maxCountO(self) (self)->f->maxCount(self) +#define maxCountG maxCountO + +#define lastO(self) (self)->f->last(self) +#define lastG lastO + +#define firstO(self) (self)->f->first(self) +#define firstG firstO + +// end class ring diff --git a/cRingInternal.h b/cRingInternal.h @@ -0,0 +1,4 @@ +#pragma once + + +static ringFunctionst *ringF = NULL; diff --git a/package.yml b/package.yml @@ -0,0 +1,15 @@ +--- + name: ring + version: 0.0.1 + description: "dynamic ring array" + bin: ./cRing.c + repository: + type: git + url: git+https://github.com/RemyNoulin/ring.git + keywords: + - utility + author: Remy + license: MIT + bugs: + url: https://github.com/RemyNoulin/ring/issues + homepage: https://github.com/RemyNoulin/ring#readme diff --git a/ring.c b/ring.c @@ -0,0 +1,59 @@ +#! /usr/bin/env sheepy + +#include "libsheepyObject.h" +#include "cRing.h" + +int argc; char **argv; + +int main(int ARGC, char** ARGV) { + + argc = ARGC; argv = ARGV; + + initLibsheepy(argv[0]); + + createAllocateRing(rg); + + if (isEmptyG(cAr(rg))) { + puts("rg is empty."); + } + + setSizeG(rg, 3); + + smallStringt *s = allocG("ring"); + pushG(cAr(rg), (baset*)s); + //pushG(cAr(rg), "elem"); + finishG(s); + + baset *r = lastG(rg); + + puts(GRN "Last:" RST); + putsG(r); + finishG(r); + + r = popG(cAr(rg), rtBaset); + + puts(GRN "Poped:" RST); + putsG(r); + finishG(r); + + r = lastG(rg); + + puts(GRN "Last:" RST); + putsG(r); + finishG(r); + + printf("Max Count: %d\n", (int)maxCountG(rg) ); + printf("Count: %d\n", (int)rCountG(rg)); + + if (isFullG(rg)) { + puts("rg is full."); + } + else { + puts("rg is not full."); + } + + terminateO(rg); + + finalizeLibsheepy(); + +}