Another commit on behalf of jimmy. (Fixing the build is hard!)
This commit is contained in:
parent
602608b60b
commit
ed9b978bda
2 changed files with 106 additions and 124 deletions
|
@ -1,135 +1,117 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "logMemory.h"
|
|
||||||
|
|
||||||
/* Could also use mod here, but 64-bit mod under intel is kinda slow,
|
|
||||||
and (in theory) gcc should only calculate ((lsn)-(x)->start) one
|
|
||||||
time...besides, I implemented it this way before I thought of using mod. ;) */
|
|
||||||
|
|
||||||
/*#define lsn_to_offset(x, lsn) \
|
|
||||||
((((lsn)-(x)->start) < (x)->size) ? \
|
|
||||||
((lsn)-(x)->start) : \
|
|
||||||
((lsn)-(x)->start) - (x)->size); */
|
|
||||||
|
|
||||||
#undef end
|
|
||||||
struct ringBufferLog_s {
|
|
||||||
/** An array of bytes that holds the contents of the ringbuffer. */
|
|
||||||
byte * buf;
|
|
||||||
/** The number of bytes in the ringbuffer */
|
|
||||||
int size;
|
|
||||||
/** The first byte in the ringbuffer that is valid. */
|
|
||||||
lsn_t start;
|
|
||||||
/** The last byte in the ringbuffer that is valid. Note that due to
|
|
||||||
the nature of a ringbuffer, end may be less than start. This
|
|
||||||
simply means that the ring buffer wraps around the end of
|
|
||||||
buf. */
|
|
||||||
lsn_t end;
|
|
||||||
/** The offset of the first byte in the ring buffer. Ignoring
|
|
||||||
wrap-around, lsn(buf[i]) = offset + (i-start). */
|
|
||||||
lsn_t offset;
|
|
||||||
} ringBufferLog_s;
|
|
||||||
|
|
||||||
|
|
||||||
#define lsn_to_offset(x, lsn) ((lsn) % (x)->size)
|
|
||||||
#define offset_to_lsn(x, lsn) ((lsn) + (x)->offset)
|
|
||||||
|
|
||||||
static int truncateLog(ringBufferLog_t * log, lsn_t lsn);
|
|
||||||
|
|
||||||
ringBufferLog_t * openLogRingBuffer(size_t size, lsn_t initialOffset) {
|
|
||||||
ringBufferLog_t * ret = malloc(sizeof(ringBufferLog_t));
|
|
||||||
ret->buf = malloc(size);
|
|
||||||
ret->size = size;
|
|
||||||
ret->start = initialOffset % size;
|
|
||||||
ret->end = initialOffset % size;
|
|
||||||
|
|
||||||
ret->offset= initialOffset / size;;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void closeLogRingBuffer(ringBufferLog_t * log) {
|
|
||||||
free(log->buf);
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
This function copies size bytes from the ringbuffer at offset
|
NOTE: Person who's using the consumer interface calls close first, (for now).
|
||||||
'offset'. size must be less than log->size.
|
|
||||||
|
|
||||||
It probably also should lie within the boundaries defined by start
|
|
||||||
and end, but this is optional.
|
|
||||||
*/
|
*/
|
||||||
static void memcpyFromRingBuffer(byte * dest, ringBufferLog_t * log, lsn_t lsn, size_t size) {
|
|
||||||
int offset = lsn_to_offset(log, lsn);
|
|
||||||
if(offset + size < log->size) {
|
#include <stdlib.h>
|
||||||
memcpy(dest, &(log->buf[offset]), size);
|
#include <lladd/ringbuffer.h>
|
||||||
|
#include <lladd/consumer.h>
|
||||||
|
#include <lladd/iterator.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
//mutex?
|
||||||
|
ringBufferLog_t * ringBuffer;
|
||||||
|
lsn_t cached_lsn;
|
||||||
|
byte * cached_value;
|
||||||
|
size_t cached_value_size;
|
||||||
|
|
||||||
|
} logMemory_fifo_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
lladdIterator_t *iterator;
|
||||||
|
lladdConsumer_t *consumer;
|
||||||
|
} lladdFifo_t;
|
||||||
|
|
||||||
|
|
||||||
|
void logMemory_init() {
|
||||||
|
/* NO-OP */
|
||||||
|
}
|
||||||
|
|
||||||
|
lladdFifo_t * logMemoryFifo(size_t size, lsn_t initialOffset) {
|
||||||
|
|
||||||
|
lladdFifo_t * fifo = (lladdFifo_t *) malloc(sizeof(lladdFifo_t));
|
||||||
|
|
||||||
|
lladdIterator_t * iterator = (lladdIterator_t *) malloc(sizeof(lladdIterator_t));
|
||||||
|
iterator->type = LOG_MEMORY_ITERATOR;
|
||||||
|
iterator->impl = malloc(sizeof(logMemory_fifo_t));
|
||||||
|
((logMemory_fifo_t *)iterator->impl)->ringBuffer = openLogRingBuffer(size, initialOffset);
|
||||||
|
|
||||||
|
lladdConsumer_t * consumer = (lladdConsumer_t *) malloc(sizeof(lladdConsumer_t));
|
||||||
|
consumer->type = LOG_MEMORY_CONSUMER;
|
||||||
|
consumer->impl = iterator->impl; /* FIXME: same logMemory_iterator_t as iterator?*/
|
||||||
|
|
||||||
|
fifo->iterator = iterator;
|
||||||
|
fifo->consumer = consumer;
|
||||||
|
|
||||||
|
return fifo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* iterator interface implementation */
|
||||||
|
|
||||||
|
/* NOTE: assumes currently that the consumer interface is done so we can
|
||||||
|
safely deallocate resources
|
||||||
|
*/
|
||||||
|
void logMemory_Iterator_close(int xid, void * impl) {
|
||||||
|
closeLogRingBuffer( ((logMemory_fifo_t *) impl)->ringBuffer );
|
||||||
|
free(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int logMemory_Iterator_next (int xid, void * impl) {
|
||||||
|
|
||||||
|
logMemory_fifo_t *fifo = (logMemory_fifo_t *) impl;
|
||||||
|
size_t size;
|
||||||
|
int lsn;
|
||||||
|
int ret;
|
||||||
|
ret = ringBufferTruncateRead((byte *)&size, fifo->ringBuffer, sizeof(size_t) );
|
||||||
|
|
||||||
|
if (ret == 0) { /* NOTE: I assume that ringBufferTruncateRead returns 0 when a read is successfull. */
|
||||||
|
|
||||||
|
/* TODO: the following might return null, in which case we should ... ? */
|
||||||
|
fifo->cached_value = realloc(fifo->cached_value, size);
|
||||||
|
|
||||||
|
lsn = ringBufferTruncateRead( fifo->cached_value, fifo->ringBuffer, size);
|
||||||
|
fifo->cached_lsn = (lsn_t)lsn;
|
||||||
|
return 1; /* FIXME: is this the right return value if there is a next value? */
|
||||||
} else {
|
} else {
|
||||||
int firstPieceLength = log->size - offset;
|
return 0; /* FIXME: is this the right return value when there is no next value? */
|
||||||
int secondPieceLength = size - firstPieceLength;
|
|
||||||
memcpy(dest, &(log->buf[offset]), firstPieceLength);
|
|
||||||
memcpy(dest + firstPieceLength, &(log->buf[0]), secondPieceLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memcpyToRingBuffer(ringBufferLog_t * log, byte *src, lsn_t lsn, size_t size) {
|
/* return the lsn */
|
||||||
int offset = lsn_to_offset(log, lsn);
|
int logMemory_Iterator_key (int xid, void * impl, byte ** key) {
|
||||||
if(offset + size < log->size) {
|
logMemory_fifo_t * fifo = (logMemory_fifo_t *) impl;
|
||||||
memcpy(&(log->buf[offset]), src, size);
|
*key = (byte *)&(fifo->cached_lsn);
|
||||||
} else {
|
return sizeof(lsn_t);
|
||||||
int firstPieceLength = log->size - offset;
|
|
||||||
int secondPieceLength = size - firstPieceLength;
|
|
||||||
memcpy(&(log->buf[offset]), src, firstPieceLength);
|
|
||||||
memcpy(&(log->buf[0]), src + firstPieceLength, secondPieceLength);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/** @todo Return values for ringBufferAppend! */
|
|
||||||
|
|
||||||
int ringBufferAppend(ringBufferLog_t * log, byte * dat, size_t size) {
|
int logMemory_Iterator_value (int xid, void * impl, byte ** value) {
|
||||||
|
logMemory_fifo_t * fifo = (logMemory_fifo_t *) impl;
|
||||||
assert(lsn_to_offset(log, log->end + size) == (lsn_to_offset(log, log->end + size)));
|
*value = fifo->cached_value;
|
||||||
|
return fifo->cached_value_size;
|
||||||
if(size > log->size) {
|
}
|
||||||
// printf("!");
|
|
||||||
return -1; // the value cannot possibly fit in the ring buffer.
|
|
||||||
}
|
|
||||||
|
|
||||||
if(log->size < (log->end-log->start) + size) {
|
|
||||||
// printf("[WX]");
|
|
||||||
return -2; // there is not enough room in the buffer right now.
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpyToRingBuffer(log, dat, log->end, size);
|
|
||||||
log->end += size; // lsn_to_offset(log, log->end + size);
|
|
||||||
|
|
||||||
|
int logMemory_Iterator_releaseTuple(int xid, void *it) {
|
||||||
|
/* NO-OP */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ringBufferTruncateRead(byte * buf, ringBufferLog_t * log, size_t size) {
|
|
||||||
if(size > log->size) {
|
|
||||||
return -1; // Request for chunk larger than entire ringbuffer
|
|
||||||
}
|
|
||||||
if(log->start + size > log->end) {
|
|
||||||
// printf("[RX]");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
memcpyFromRingBuffer(buf, log, lsn_to_offset(log, log->start), size);
|
|
||||||
|
|
||||||
return truncateLog(log, log->start + size);
|
|
||||||
|
|
||||||
|
|
||||||
|
/* consumer implementation */
|
||||||
|
|
||||||
|
|
||||||
|
void logMemory_Tconsumer_close(int xid, lladdConsumer_t *it){
|
||||||
|
/* Currently this doesn't have to do anything */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** static because it does no error checking. */
|
int Tconsumer_push(int xid, lladdConsumer_t *it, byte *key, size_t keySize, byte *val, size_t Valsize) {
|
||||||
static int truncateLog(ringBufferLog_t * log, lsn_t lsn) {
|
ringBufferAppend( ((logMemory_fifo_t *) it->impl)->ringBuffer, (byte *)&Valsize, sizeof(size_t) );
|
||||||
|
ringBufferAppend( ((logMemory_fifo_t *) it->impl)->ringBuffer, val, Valsize);
|
||||||
int newStart = lsn_to_offset(log, lsn);
|
|
||||||
|
|
||||||
if(newStart < lsn_to_offset(log, log->start)); // buffer wrapped.
|
|
||||||
|
|
||||||
log->offset += log->size;
|
|
||||||
log->start = lsn;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ terms specified in this license.
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <check.h>
|
#include <check.h>
|
||||||
|
|
||||||
#include "../../src/lladd/logger/logMemory.h"
|
#include <lladd/ringbuffer.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "../check_includes.h"
|
#include "../check_includes.h"
|
||||||
|
|
Loading…
Reference in a new issue