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:
A | cRing.c | | | 271 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cRing.h | | | 110 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cRingInternal.h | | | 4 | ++++ |
A | package.yml | | | 15 | +++++++++++++++ |
A | ring.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();
+
+}