Some documentation, and a few minor cleanups.
diff --git a/median.c b/median.c
index 9a6f183..6c413ef 100644
--- a/median.c
+++ b/median.c
@@ -74,6 +74,8 @@
b->data[b->occupancy++] = data;
}
+// Check if there is space in some block and if there is, then
+// make that block the current block.
unsigned int occupy_available_empty_block(metadata_t * m) {
size_t idx = 0;
for(unsigned char * ptr = (unsigned char *) m->data; // Start of the data blocks.
@@ -91,15 +93,24 @@
return 0;
}
-void create_empty_block(metadata_t * m) {
+unsigned int create_empty_block(metadata_t * m) {
// TODO
+ return 0;
}
// Shift the current block.
-void shift_current_block(metadata_t * m) {
+unsigned int shift_current_block(metadata_t * m) {
if(!occupy_available_empty_block(m)) {
- create_empty_block(m);
+ if(create_empty_block(m)) {
+ // Now there should be an empty block!
+ // So occupy it.
+ occupy_available_empty_block(m);
+ } else {
+ // Stuck we are, block not.
+ return 0;
+ }
}
+ return 1;
}
@@ -163,15 +174,40 @@
}
+// Insert data into the buffer.
+// We could have made this more concise and pretty if we used short-circuit
+// execution of the boolean condition..
+//
+// if (current_block_has_space(m) || shift_current_block(m)) {
+// insert_data_into_current_block(m,data);
+// return MEDIAN_OK;
+// } else {
+// return MEDIAN_ERROR_MAX_N_EXCEEDED;
+// }
+//
+// But this code is harder to read, because of the side
+// effect issue.
median_error_t median_insert_data(median_buffer_t buffer,
median_data_t data){
metadata_t * m = (metadata_t *) buffer;
+ // If there is space in the current block..
if(current_block_has_space(m)) {
+ // Insert data into the current block. This
+ // call is to an unchecked method, which will
+ // never fail.
insert_data_into_current_block(m,data);
} else {
- shift_current_block(m);
- return median_insert_data(buffer,data);
+ // Current block is full. So try and shift it.
+ if(shift_current_block(m)) {
+ // The current block has shifted successfully.
+ // So we can now call the unchecked method again.
+ insert_data_into_current_block(m,data);
+ } else {
+ // Failed to shift block. Stuck we are.
+ return MEDIAN_ERROR_MAX_N_EXCEEDED;
+ }
}
+ // Everything worked. So return MEDIAN_OK.
return MEDIAN_OK;
}
@@ -180,17 +216,23 @@
return MEDIAN_OK;
}
+// Dump the state to stderr.
median_error_t median_dump_stderr(const median_buffer_t buffer){
+ // First print out all the metadata.
metadata_t * m = (metadata_t *) buffer;
blockdata_t * current = get_current_block(m);
- fprintf(stderr, "Metadata:\n Next GID:%d\n nMembers:%d\n nLevels:%d\n",m->gid,(unsigned)m->nMembers,(unsigned)m->nLevels);
- fprintf(stderr, "Current Block:%d\n", current->id);
+ fprintf(stderr, "Metadata:\n Next GID:%d\n nMembers:%d\n nLevels:%d\n CurrentBlock:%d\n",m->gid,(unsigned)m->nMembers,(unsigned)m->nLevels, current->id);
+
+ // Now dump the blocks.
for(unsigned char * ptr = (unsigned char *) m->data; // Start of the data blocks.
ptr <= (m->data + buffersize(m) - blocksize(m)); // The next block will fit into the buffer.
ptr += blocksize(m)) { // Advance by a block
blockdata_t * b = (blockdata_t *)ptr;
fprintf(stderr, "Block:%d\n Level:%d\n Occupancy:%d\n", b->id,(unsigned)b->level,(unsigned)b->occupancy);
- stderr_hexdmp("Data:",(unsigned char *)(b->data),256);
+ // For every block, dump the first 8 keys in the block.
+ stderr_hexdmp("Data:",(unsigned char *)(b->data),8*sizeof(median_data_t));
}
+
+ // Done, return MEDIAN_OK.
return MEDIAN_OK;
}