M Makefile => Makefile +1 -1
@@ 1,4 1,4 @@
-all: ringpage
+all: test lib
CFLAGS := -lc \
-Wall \
M ouroboros.h => ouroboros.h +2 -0
@@ 46,4 46,6 @@ enum ringbuf_add_record_result ringbuf_add_record(struct ringbuf*, struct record
struct ringpage ringpage_create(FILE*);
struct ringbuf ringpage_create_ringbuf(struct ringpage*);
+int ringpage_add_page_from_ringbuf(struct ringpage*, struct ringbuf*);
void ringpage_destroy(struct ringpage*);
+
M ringbuf.c => ringbuf.c +3 -1
@@ 16,7 16,9 @@ const size_t RECORDS_PER_PAGE =
const unsigned int TOTAL_RECORD_BUFFER_SIZE = RECORDS_PER_PAGE * sizeof(struct record);
struct ringbuf ringbuf_create(void) {
- struct record* records = calloc(RECORDS_PER_PAGE, sizeof(struct record));
+ // Include the tail because we'll need to set it when/if we serialize this buf to
+ // disk as a page.
+ struct record* records = malloc(PAGE_SIZE + PAGE_TAIL_SIZE);
struct ringbuf rb = {
.head = 0,
.length = 0,
M ringpage.c => ringpage.c +46 -0
@@ 121,6 121,52 @@ struct ringbuf ringpage_create_ringbuf(struct ringpage* rp) {
return rb;
}
+int ringpage_write_page(struct ringpage* rp, struct page* page) {
+ if (fseek(rp->file, sizeof(struct page) * ringpage_tail_index(rp), SEEK_SET)) {
+ fprintf(stderr, "Unable to seek to offset.");
+ return -1;
+ }
+ return fwrite(page, sizeof(struct page), 1, rp->file);
+}
+
+uint64_t ringpage_next_seq(struct ringpage* rp) {
+ unsigned int tail_index = ringpage_tail_index(rp);
+ // If we looped around, flip inc
+ if (tail_index == 0) {
+ rp->inc = !rp->inc;
+ }
+ if (rp->inc) {
+ return tail_index + 1;
+ } else {
+ return NUM_PAGES - tail_index;
+ }
+}
+
+int ringpage_add_page_from_ringbuf(struct ringpage* rp, struct ringbuf* rb) {
+ // Converts a ringbuf's records into a page and saves it to disk, consuming the
+ // ringbuf (ie. freeing the records).
+ enum ringbufflags result = ringbuf_normalize(rb);
+ switch (result) {
+ case RB_OK:
+ break;
+ default:
+ fprintf(stderr, "There was an error normalizing the ringbuf. Code: %i", result);
+ }
+ struct tail* t = (struct tail*)rb->records + (sizeof(struct record) * RECORDS_PER_PAGE);
+ // Get the next seq
+ uint64_t next_seq = ringpage_next_seq(rp);
+ t->seq = next_seq;
+ // TODO: implement CRC
+ t->crc = 0;
+ struct page* p = (struct page*)rb->records;
+ if(ringpage_write_page(rp, p)) {
+ fprintf(stderr, "Unable to write page");
+ return -1;
+ }
+ ringbuf_destroy(rb);
+ return 0;
+}
+
void ringpage_destroy(struct ringpage* rp) {
if (rp->body != NULL)
free(rp->body);
M tests/make_test_buf.c => tests/make_test_buf.c +20 -11
@@ 4,20 4,29 @@
int main(void) {
FILE* f = fopen("./test.bin", "w+");
if (f == NULL) {
- fprintf(stderr,"Error opening test.bin");
+ fprintf(stderr,"Error opening test.bin\n");
return -1;
}
- struct ringbuf rb = ringbuf_create();
- for (unsigned long i = 0; i < RECORDS_PER_PAGE; i++) {
- struct record r = {
- .ts = i,
- .v = i*2,
- };
- enum ringbuf_add_record_result result = ringbuf_add_record(&rb, &r);
- if (result != ADD_RECORD_OK) {
- fprintf(stderr,"Failed to add record at index %li", i);
- return -1;
+ fprintf(stderr, "Creating ringpage...\n");
+ struct ringpage rp = ringpage_create(f);
+ struct ringbuf rb;
+ for(int z = 0; z < 4; z++) {
+ fprintf(stderr, "Creating ringbuf...\n");
+ rb = ringbuf_create();
+ for (unsigned long i = 0; i < RECORDS_PER_PAGE; i++) {
+ struct record r = {
+ .ts = i,
+ .v = i*2,
+ };
+ //fprintf(stderr, "Adding record with ts=%li and v=%li\n", r.ts, r.v);
+ enum ringbuf_add_record_result result = ringbuf_add_record(&rb, &r);
+ if (result != ADD_RECORD_OK) {
+ fprintf(stderr,"Failed to add record at index %li\n", i);
+ return -1;
+ }
}
+ fprintf(stderr, "Saving ringbuf to file.\n");
+ ringpage_add_page_from_ringbuf(&rp, &rb);
}
fprintf(stderr, "Done.");
return 0;
M tests/test_ringpage.c => tests/test_ringpage.c +1 -0
@@ 15,6 15,7 @@ void test_ringpage_to_ringbuf(CuTest* tc) {
FILE* f = fopen("./test.bin", "w+");
struct ringpage rp = ringpage_create(f);
+ ringpage_destroy(&rp);
}
CuSuite* pagebuf_get_suite() {