better verbose messages

This commit is contained in:
Kacper Donat 2018-12-14 22:51:55 +01:00
parent bafb629b6a
commit 66d4591ebb
4 changed files with 59 additions and 27 deletions

View File

@ -3,8 +3,9 @@
#define VERBOSITY_QUIET -1
#define VERBOSITY_NORMAL 0
#define VERBOSITY_VERBOSE 1
#define VERBOSITY_DEBUG 2
#define VERBOSITY_DEBUG 1
#define VERBOSITY_VERBOSE 2
#define VERBOSITY_VERY_VERBOSE 3
#include <stdio.h>
#include "optparse.h"

65
index.c
View File

@ -10,11 +10,15 @@
#define BTREE_ERR_CANNOT_OPEN_FILE -1
#define BTREE_ERR_PAGE_SIZE_DIFFERENT -2
#define BTREE_OPTIMIZE_RECORDS_MIN 10
#define BTREE_OPTIMIZE_THRESHOLD 0.1
#define SWAP(type, x, y) do { type __tmp__; __tmp__ = y; y = x; x = __tmp__; } while (0)
/* private functions */
void _btree_insert_into_node(btree_t *tree, btree_node_t *node, btree_entry_t *entry);
void _btree_remove_from_node(btree_t *tree, btree_node_t *node, unsigned index);
void _btree_optimize_if_needed(btree_t *tree) ;
int _btree_save_header(btree_t *tree)
{
@ -42,14 +46,14 @@ page_t _btree_alloc(btree_t *tree)
page += bit + 1;
printfv(VERBOSITY_DEBUG, "[alloc] allocated page %zu.\n", page);
printfv(VERBOSITY_VERBOSE, "[alloc] allocated page %zu.\n", page);
return page;
}
void _btree_page_free(btree_t *tree, page_t page)
{
printfv(VERBOSITY_DEBUG, "[alloc] freeing page %zu.\n", page);
printfv(VERBOSITY_VERBOSE, "[alloc] freeing page %zu.\n", page);
uint8_t bitmap[PAGE_SIZE];
file_read(tree->file, 1 + (page / (PAGE_SIZE * 8)) * PAGE_SIZE, bitmap, PAGE_SIZE);
@ -88,7 +92,7 @@ bool _btree_stack_empty(btree_t *tree)
void _btree_stack_push(btree_t *tree, btree_node_t *node, unsigned n)
{
printfv(VERBOSITY_DEBUG, "[btree] Pushing %zu page on parent stack, entry index %u\n", node->page, n);
printfv(VERBOSITY_VERBOSE, "[btree] Pushing %zu page on parent stack, entry index %u\n", node->page, n);
tree->trace.current++;
tree->trace.current->node = *node;
tree->trace.current->entry = btree_get_entry(&tree->trace.current->node, n);
@ -149,7 +153,7 @@ unsigned _btree_concat_entries(void* current, size_t na, void* added, size_t nb)
void _btree_node_insert_entry(btree_node_t* node, btree_entry_t entry)
{
printfv(VERBOSITY_DEBUG, "[btree] inserting { %zu < %zu > %zu } on %zu\n", entry.left, entry.key, entry.right, node->page);
printfv(VERBOSITY_VERBOSE, "[btree] inserting { %zu < %zu > %zu } on %zu\n", entry.left, entry.key, entry.right, node->page);
_btree_concat_entries(node->entries, node->header.entries, &entry, 1);
node->header.entries++;
@ -371,10 +375,10 @@ void _btree_split_node(btree_t *tree, btree_node_t *old, btree_entry_t *entry)
tree->header.root = parent->page;
_btree_save_header(tree);
printfv(VERBOSITY_DEBUG, "[btree] designated new root %zu.\n", parent->page);
printfv(VERBOSITY_DEBUG, "[btree] Designated new root %zu.\n", parent->page);
};
printfv(VERBOSITY_DEBUG, "[btree] spliting node %zu.\n", old->page);
printfv(VERBOSITY_DEBUG, "[btree] Spliting node %zu.\n", old->page);
btree_entry_t parent_entry = *NODE_ENTRY(buffer, half);
@ -457,7 +461,7 @@ page_t btree_insert(btree_t *tree, record_t record)
btree_node_t node;
if (btree_find(tree, key, NULL, &node, NULL) != PAGE_NONE) {
printfv(VERBOSITY_DEBUG, "[btree] record with key %zu already exists.\n", key);
printfv(VERBOSITY_DEBUG, "[btree] Record with key %zu already exists.\n", key);
return PAGE_NONE;
}
@ -465,12 +469,18 @@ page_t btree_insert(btree_t *tree, record_t record)
btree_entry_t entry = { PAGE_NONE, key, offset, PAGE_NONE };
_btree_insert_into_node(tree, &node, &entry);
tree->header.changes++;
tree->header.records++;
_btree_optimize_if_needed(tree);
return node.page;
}
void _btree_merge(btree_t *tree, btree_node_t* left, btree_node_t* right)
{
printfv(VERBOSITY_DEBUG, "[btree] merging %zu with %zu.\n", left->page, right->page);
printfv(VERBOSITY_DEBUG, "[btree] Merging %zu with %zu.\n", left->page, right->page);
size_t nl = left->header.entries,
nr = right->header.entries,
@ -501,7 +511,7 @@ void _btree_merge(btree_t *tree, btree_node_t* left, btree_node_t* right)
left->header.flags |= NODE_IS_ROOT;
tree->header.root = left->page;
printfv(VERBOSITY_DEBUG, "[btree] designated new root %zu.\n", left->page);
printfv(VERBOSITY_DEBUG, "[btree] Designated new root %zu.\n", left->page);
} else {
_btree_write_node(&parent->node, tree, parent->node.page);
}
@ -518,7 +528,7 @@ void _btree_fix_underflow(btree_t *tree, btree_node_t *node) {
_btree_load_node(&sibling, tree, siblings.left);
entry = siblings.left_entry;
if (sibling.header.entries + node->header.entries >= 2*tree->header.d) {
printfv(VERBOSITY_DEBUG, "[btree] rebalancing with left sibling %zu.\n", siblings.left);
printfv(VERBOSITY_VERBOSE, "[btree] rebalancing with left sibling %zu.\n", siblings.left);
_btree_rebalance(tree, &sibling, node, siblings.left_entry);
return;
}
@ -528,13 +538,13 @@ void _btree_fix_underflow(btree_t *tree, btree_node_t *node) {
_btree_load_node(&sibling, tree, siblings.right);
entry = siblings.right_entry;
if (sibling.header.entries + node->header.entries >= 2*tree->header.d) {
printfv(VERBOSITY_DEBUG, "[btree] rebalancing with right sibling %zu.\n", siblings.right);
printfv(VERBOSITY_VERBOSE, "[btree] rebalancing with right sibling %zu.\n", siblings.right);
_btree_rebalance(tree, node, &sibling, siblings.right_entry);
return;
}
}
printfv(VERBOSITY_DEBUG, "[btree] unable to rebalance.\n");
printfv(VERBOSITY_DEBUG, "[btree] Enable to rebalance.\n");
if (siblings.right != PAGE_NONE) {
_btree_merge(tree, node, &sibling);
@ -563,7 +573,7 @@ void _btree_remove_from_node(btree_t *tree, btree_node_t *node, unsigned index)
node->header.entries = m;
if ((~node->header.flags & NODE_IS_ROOT) && node->header.entries < tree->header.d) {
printfv(VERBOSITY_DEBUG, "[btree] underflow in %zu.\n", node->page);
printfv(VERBOSITY_DEBUG, "[btree] Underflow in %zu.\n", node->page);
_btree_fix_underflow(tree, node);
} else {
_btree_write_node(node, tree, node->page);
@ -578,7 +588,7 @@ page_t btree_remove(btree_t *tree, record_key_t key)
unsigned index;
if (btree_find(tree, key, NULL, &node, &index) == PAGE_NONE) {
printfv(VERBOSITY_DEBUG, "[btree] record with key %zu does not exist.\n", key);
printfv(VERBOSITY_DEBUG, "[btree] Record with key %zu does not exist.\n", key);
// 404
return PAGE_NONE;
}
@ -586,11 +596,11 @@ page_t btree_remove(btree_t *tree, record_key_t key)
entry = btree_get_entry(&node, index);
if (node.header.flags & NODE_IS_LEAF) {
printfv(VERBOSITY_DEBUG, "[btree] removing record with key %zu from leaf %zu.\n", entry->key, node.page);
printfv(VERBOSITY_DEBUG, "[btree] Removing record with key %zu from leaf %zu.\n", entry->key, node.page);
_btree_remove_from_node(tree, &node, index);
_btree_write_node(&node, tree, node.page);
} else {
printfv(VERBOSITY_DEBUG, "[btree] removing record with key %zu from node %zu.\n", entry->key, node.page);
printfv(VERBOSITY_DEBUG, "[btree] Removing record with key %zu from node %zu.\n", entry->key, node.page);
btree_node_t *replacement;
btree_entry_t *replaced;
@ -608,7 +618,7 @@ page_t btree_remove(btree_t *tree, record_key_t key)
replaced = NODE_ENTRY(node.entries, 0);
entry = btree_get_entry(replacement, index);
printfv(VERBOSITY_DEBUG, "[btree] exchanging %zu with %zu.\n", entry->key, replaced->key);
printfv(VERBOSITY_DEBUG, "[btree] Exchanging %zu with %zu.\n", entry->key, replaced->key);
SWAP(record_key_t, replaced->key, entry->key);
SWAP(offset_t, replaced->location, entry->location);
_btree_write_node(replacement, tree, replacement->page);
@ -616,13 +626,18 @@ page_t btree_remove(btree_t *tree, record_key_t key)
_btree_remove_from_node(tree, &node, 0);
}
tree->header.changes++;
tree->header.records--;
_btree_optimize_if_needed(tree);
return node.page;
}
bool btree_update(btree_t *tree, record_key_t key, record_t record)
{
if (record.key != key) {
printfv(VERBOSITY_DEBUG, "[btree] update key mismatch, removing %zu and adding %zu.\n", key, record.key);
printfv(VERBOSITY_DEBUG, "[btree] Update key mismatch, removing %zu and adding %zu.\n", key, record.key);
btree_remove(tree, key);
return btree_insert(tree, record) != PAGE_NONE;
}
@ -663,6 +678,8 @@ page_t btree_read_record(btree_t *tree, record_key_t key, record_t *record)
void btree_close(btree_t* tree)
{
printfv(VERBOSITY_DEBUG, "[btree] Closing index %s.\n", tree->file->filename);
_btree_save_header(tree);
file_close(tree->file);
tape_close(tree->main);
}
@ -673,6 +690,15 @@ void btree_flush(btree_t* tree)
file_flush(tree->main->file);
}
void _btree_optimize_if_needed(btree_t *tree)
{
double ratio = (double)tree->header.changes / (double)tree->header.records;
if (tree->header.records > BTREE_OPTIMIZE_RECORDS_MIN && ratio > BTREE_OPTIMIZE_THRESHOLD) {
printfv(VERBOSITY_DEBUG, "[btree] Auto optimization triggered.\n");
btree_optimize(tree);
}
}
void _btree_optimize_page(btree_t* tree, tape_t* tmp, page_t page)
{
if (!page) return;
@ -696,10 +722,13 @@ void _btree_optimize_page(btree_t* tree, tape_t* tmp, page_t page)
void btree_optimize(btree_t *tree)
{
char tmp[PATH_MAX + 4], old[PATH_MAX];
strcpy(old, tree->main->file->filename);
sprintf(tmp, "%s.tmp", old);
printfv(VERBOSITY_DEBUG, "[btree] Optimizing btree using temp file %s.\n", tmp);
tape_t *temp = tape_open(tmp, "wb+");
_btree_optimize_page(tree, temp, tree->header.root);
tape_close(temp);

View File

@ -23,7 +23,9 @@ typedef struct {
size_t page_size; /* 8 bytes long */
page_t root; /* 8 bytes long */
char main[256]; /* 256 bytes long */
} btree_header_t; /* 280 bytes long */
size_t records; /* 8 bytes long */
size_t changes; /* 8 bytes long */
} btree_header_t; /* 296 bytes long */
typedef struct {
uint16_t flags;

12
io.c
View File

@ -19,7 +19,7 @@ file_t* file_open(const char* filename, const char* mode)
return NULL;
}
printfv(VERBOSITY_DEBUG, "[io] File %s opened in %s with page size %zu.\n", filename, mode, PAGE_SIZE);
printfv(VERBOSITY_VERY_VERBOSE, "[io] File %s opened in %s with page size %zu.\n", filename, mode, PAGE_SIZE);
file_t* result = malloc(sizeof(file_t));
result->file = handle;
@ -34,7 +34,7 @@ void file_close(file_t* file)
{
file_flush(file);
printfv(VERBOSITY_DEBUG, "[io] Closing file %s.\n", file->filename);
printfv(VERBOSITY_VERY_VERBOSE, "[io] Closing file %s.\n", file->filename);
fclose(file->file);
free(file->filename);
@ -48,14 +48,14 @@ size_t file_read(file_t* file, page_t page, void* buffer, size_t length)
page_cache_entry_t *entry = _file_load_page(file, page);
memcpy(buffer, entry->data, length);
printfv(VERBOSITY_DEBUG, "[io] Reading page %zu in %s (%zu bytes).\n", page, file->filename, entry->size);
printfv(VERBOSITY_VERY_VERBOSE, "[io] Reading page %zu in %s (%zu bytes).\n", page, file->filename, entry->size);
return entry->size;
}
size_t file_write(file_t* file, page_t page, const void* buffer, size_t length)
{
printfv(VERBOSITY_DEBUG, "[io] Writing page %zu in %s (%zu bytes).\n", page, file->filename, length);
printfv(VERBOSITY_VERY_VERBOSE, "[io] Writing page %zu in %s (%zu bytes).\n", page, file->filename, length);
writes_all++;
page_cache_entry_t *entry = _file_load_page(file, page);
@ -92,7 +92,7 @@ page_cache_entry_t *_file_load_page(file_t* file, page_t page)
memset(entry->data, 0, PAGE_SIZE);
entry->size = fread(entry->data, 1, PAGE_SIZE, file->file);
if (entry->size) {
printfv(VERBOSITY_DEBUG, "[io] Loading page %u of %s (%zu bytes).\n", page, file->filename, entry->size);
printfv(VERBOSITY_VERY_VERBOSE, "[io] Loading page %u of %s (%zu bytes).\n", page, file->filename, entry->size);
reads++;
}
@ -105,7 +105,7 @@ page_cache_entry_t *_file_load_page(file_t* file, page_t page)
void _file_flush_page(file_t *file, page_cache_entry_t *entry)
{
if (entry->flags & PAGE_PRESENT && entry->flags & PAGE_DIRTY) {
printfv(VERBOSITY_DEBUG, "[io] Flushing page %u to %s (%zu bytes).\n", entry->page, file->filename, entry->size);
printfv(VERBOSITY_VERY_VERBOSE, "[io] Flushing page %u to %s (%zu bytes).\n", entry->page, file->filename, entry->size);
fseek(file->file, entry->page * PAGE_SIZE, SEEK_SET);
fwrite(entry->data, 1, entry->size, file->file);