Permalink
Browse files

- implement ring buffering

- add tests for ring
  • Loading branch information...
1 parent bca515d commit ce6fabf205514a1c6ac9acd7513148544c385db8 @jordansissel jordansissel committed Aug 5, 2012
Showing with 94 additions and 13 deletions.
  1. +44 −6 ring.c
  2. +17 −7 ring.h
  3. +33 −0 test_ring.c
View
50 ring.c
@@ -1,12 +1,50 @@
#include "ring.h"
#include <jemalloc/jemalloc.h>
-struct ring *ring_new_size(size_t count, size_t object_size);
- struct ring *r;
- r = malloc(sizeof(struct ring));
- r->head = 0;
- r->tail = 0;
+struct ring *ring_new_size(size_t size) {
+ struct ring *r = malloc(sizeof(struct ring));
+ r->writer = 0;
+ r->reader = 0;
+ r->count = 0;
r->size = size;
- r->buffer = malloc(count * object_size);
+ r->buffer = malloc(r->size * sizeof(void *));
return r;
} /* ring_new_size */
+
+
+inline int ring_is_empty(struct ring *ring) {
+ return ring->count == 0;
+} /* ring_is_empty */
+
+int ring_is_full(struct ring *ring) {
+ return ring->count == ring->size;
+} /* ring_is_full */
+
+int ring_pop(struct ring *ring, void **object_ret) {
+ if (ring_is_empty(ring)) {
+ return RING_IS_EMPTY;
+ }
+
+ *object_ret = ring->buffer[ring->reader];
+
+ ring->reader++;
+ ring->count--;
+ if (ring->reader == ring->size) {
+ ring->reader = 0; /* wrap around */
+ }
+ return RING_OK;
+} /* ring_pop */
+
+int ring_push(struct ring *ring, void *object) {
+ if (ring_is_full(ring)) {
+ return RING_IS_FULL;
+ }
+
+ ring->buffer[ring->writer] = object;
+ ring->writer++;
+ ring->count++;
+ if (ring->writer == ring->size) {
+ ring->writer = 0; /* wrap around */
+ }
+ return RING_OK;
+} /* ring_push */
View
24 ring.h
@@ -1,15 +1,25 @@
+#ifndef _RING_H_
+#define _RING_H_
+#include <sys/types.h>
-struct fifo {
- size_t head;
- size_t tail;
+struct ring {
+ size_t writer;
+ size_t reader;
size_t size;
- void *buffer[]; /* array of pointers to whatever objects we're storing */
+ size_t count;
+ void **buffer; /* array of pointers to whatever objects we're storing */
};
-struct ring *ring_new_size(size_t count, size_t object_size);
+#define RING_OK 0x00
+#define RING_IS_EMPTY 0x01
+#define RING_IS_FULL 0x02
+
+struct ring *ring_new_size(size_t count);
int ring_is_empty(struct ring *ring);
int ring_is_full(struct ring *ring);
-void *ring_pop(struct ring *ring);
-void ring_push(struct ring *ring, void *object);
+int ring_pop(struct ring *ring, void **object_ret);
+int ring_push(struct ring *ring, void *object);
+
+#endif /* _RING_H_ */
View
@@ -0,0 +1,33 @@
+#include "ring.h"
+#include <string.h>
+#include "insist.h"
+
+int main(void) {
+ struct ring *ring;
+ ring = ring_new_size(4);
+
+ insist(ring_is_empty(ring), "A new ring must be empty");
+ insist(ring_push(ring, "Hello world 1") == RING_OK, "Pushing 1 into a 4-slot ring must be OK");
+ insist(ring_push(ring, "Hello world 2") == RING_OK, "Pushing 2 into a 4-slot ring must be OK");
+ insist(ring_push(ring, "Hello world 3") == RING_OK, "Pushing 3 into a 4-slot ring must be OK");
+ insist(ring_push(ring, "Hello world 4") == RING_OK, "Pushing 4 into a 4-slot ring must be OK");
+ insist(ring_push(ring, "Hello world 5") == RING_IS_FULL, "Pushing 5 into a 4-slot ring must fail ");
+ insist(ring_is_full(ring), "The ring must be full at this point");
+ insist(!ring_is_empty(ring), "Ring must not be empty at this point");
+
+ char *val;
+ insist(ring_pop(ring, (void **)&val) == RING_OK, "Popping from a full ring must succeed");
+ insist(strcmp(val, "Hello world 1") == 0, "Got the wrong string?");
+ insist(ring_pop(ring, (void **)&val) == RING_OK, "Popping on a non-empty ring must succeed");
+ insist(strcmp(val, "Hello world 2") == 0, "Got the wrong string?");
+ insist(ring_pop(ring, (void **)&val) == RING_OK, "Popping on a non-empty ring must succeed");
+ insist(strcmp(val, "Hello world 3") == 0, "Got the wrong string?");
+ insist(ring_pop(ring, (void **)&val) == RING_OK, "Popping on a non-empty ring must succeed");
+ insist(strcmp(val, "Hello world 4") == 0, "Got the wrong string?");
+ insist(ring_pop(ring, (void **)&val) == RING_IS_EMPTY, "Pop on an empty ring must fail");
+ insist(ring_is_empty(ring), "Ring must be empty at this point");
+ insist(!ring_is_full(ring), "Ring must not be full at this point");
+
+ printf("%s OK\n", __FILE__);
+ return 0;
+} /* main */

0 comments on commit ce6fabf

Please sign in to comment.