More cleanup

Added slides as pdf.

Refactored keydb_insert; moved code into new_subkey_tree.

Started work on count_command, but it doesn't work correctly.
This commit is contained in:
Joseph Rothrock 2012-10-31 12:24:16 -07:00
parent fdb2b51003
commit 2f39effb3f
4 changed files with 120 additions and 49 deletions

BIN
roxanne.pdf Normal file

Binary file not shown.

View File

@ -272,15 +272,16 @@ int start_listening(char* host, char* port, int backlog) {
int extract_command(char* msg, int msglen) {
char* commands[5] = { "create /", // 0
"read /", // 1
"delete /", // 2
"keys /", // 3
"quit"}; // 4
char* commands[6] = { "quit", // 0
"create /", // 1
"read /", // 2
"delete /", // 3
"keys /", // 4
"count /"}; // 5
int i = 0;
int cmdlen;
int max_chars = 0;
for (; i < 5; i++) {
for (; i < 6; i++) {
cmdlen = strlen(commands[i]);
max_chars = msglen < cmdlen ? msglen : cmdlen;
if (memcmp(commands[i], msg, max_chars) == 0) return(i);
@ -703,24 +704,29 @@ int guts(int accept_fd, int listen_fd) {
switch (extract_command(msg, msglen)) {
case 0: // create
case 0: // quit
cleanup_and_exit();
break;
case 1: // create
create_command(msg, response);
break;
case 1: // read
case 2: // read
read_command(msg, response);
break;
case 2: // delete
case 3: // delete
delete_command(msg, response);
break;
case 3: // subkeys
case 4: // subkeys
keys_command(msg, response);
break;
case 4: // quit
cleanup_and_exit();
case 5: // count
count_command(msg, response);
break;
default:
sprintf(response, "Unknown command.\n");
@ -996,18 +1002,25 @@ void keys_command(char msg[], char response[]) {
return;
}
if ((node = keydb_find(KEYDB_FD, part, pos))) {
pos = node->next;
free(node);
if (pos == 0) { // There is no next subtree.
sprintf(response, "No subkeys.\n");
return;
}
} else {
node = keydb_find(KEYDB_FD, part, pos);
if (!(node = keydb_find(KEYDB_FD, part, pos))) {
sprintf(response, "Not found.\n");
return;
}
if (node->refcount <= 0) {
sprintf(response, "Not found.\n");
return;
}
pos = node->next;
free(node);
if (pos == 0) { // There is no next subtree.
sprintf(response, "No subkeys.\n");
return;
}
}
keydb_tree(KEYDB_FD, pos, &list);
@ -1027,6 +1040,58 @@ void keys_command(char msg[], char response[]) {
return;
}
void count_command(char msg[], char response[]) {
char* part = NULL;
char key[KEY_LEN] = "";
int length = 0;
int retval;
int refcount = 0;
int64_t pos = 0;
struct keydb_node *node;
struct keydb_column *list, *tmp, *cursor;
list = NULL;
part = strtok(msg, "/");
for (part = strtok(NULL, "\r\n/"); part; part = strtok(NULL, "\r\n/")) {
length += strlen(part);
if (length > KEY_LEN - 1) {
sprintf(response, "Key too long.\n");
part = NULL;
return;
}
if ((node = keydb_find(KEYDB_FD, part, pos))) {
pos = node->next;
refcount = node->refcount;
free(node);
if (pos == 0) { // There is no next subtree.
sprintf(response, "%d\n", refcount);
return;
}
} else {
sprintf(response, "Not found.\n");
return;
}
}
// Sum all the refcounts of all keys in the root tree.
// This is for 'count /'.
keydb_tree(KEYDB_FD, pos, &list);
while (list) {
if (list->column[0] != '\0') {
refcount += list->refcount;
}
tmp = list->next;
free(list);
list = tmp;
}
sprintf(response, "%d\n", refcount);
return;
}
void usage(char *argv) {
fprintf(stderr, "usage: %s [-h listen_addr] [-p listen_port] [-d /path/to/db/directory]\n", argv);
exit(-1);

View File

@ -152,3 +152,5 @@ struct keydb_node* keydb_find(int fd, char *key, int64_t pos);
void* keydb_tree(int fd, int64_t pos, struct keydb_column **list);
int find_free_key_node(int keydb_fd);
int connect_and_add_node(int direction, struct keydb_node* buffer, char column[], int pos, int fd);
int new_subkey_tree(int fd, char column[], int64_t pos, struct keydb_node *buffer);
void count_command(char msg[], char response[]);

View File

@ -190,13 +190,11 @@ int composite_insert(int fd, struct keydb_column *tuple) {
int64_t pos = 0;
int64_t previous_pos = 0;
//sem_wait(KEYDB_LOCK);
keydb_lock(pos);
previous_pos = pos;
pos = keydb_insert(fd, tuple->column, pos, false);
keydb_unlock(previous_pos);
if (pos == -1) {
//sem_post(KEYDB_LOCK);
return -1;
}
tuple = tuple->next;
@ -207,17 +205,45 @@ int composite_insert(int fd, struct keydb_column *tuple) {
pos = keydb_insert(fd, tuple->column, pos, true);
keydb_unlock(previous_pos);
if (pos == -1){
//sem_post(KEYDB_LOCK);
return -1;
}
tuple = tuple->next;
};
//sem_post(KEYDB_LOCK);
return 0;
}
int new_subkey_tree(int fd, char column[], int64_t pos, struct keydb_node *buffer) {
// Create a new subkey tree below the given keydb_node.
int64_t next_pos;
if ((next_pos = find_free_key_node(fd)) == -1) {
fprintf(stderr, "find_free_key_node_failed.\n");
free(buffer);
return -1;
}
buffer->next = next_pos;
if (pwrite(fd, buffer, sizeof(struct keydb_node), pos) == -1) {
perror("pwrite() failed in new_subkey_tree.");
free(buffer);
return -1;
}
bzero(buffer, sizeof(struct keydb_node));
strcpy(buffer->column, column);
buffer->refcount = 1;
buffer->pos = next_pos;
if (pwrite(fd, buffer, sizeof(struct keydb_node), next_pos) == -1) {
perror("pwrite() failed in new_subkey_tree.");
free(buffer);
return -1;
}
free(buffer);
return next_pos;
}
int keydb_insert(int fd, char column[], int64_t pos, bool go_next) {
// inserts a node in the keydb tree. The go_next flag determines
// whether or not the key goes into the binary tree pointed at by
@ -244,37 +270,15 @@ int keydb_insert(int fd, char column[], int64_t pos, bool go_next) {
return -1;
}
if (go_next) {
if (n == 0) { // We can't go 'next' off a record that doesn't exist.
fprintf(stderr, "pos is at EOF but we need to read a real record.\n");
free(buffer);
return -1;
}
if (buffer->next == 0) { // We're making a new subkey tree.
if ((next_pos = find_free_key_node(fd)) == -1) {
fprintf(stderr, "find_free_key_node_failed.\n");
free(buffer);
return -1;
}
if (buffer->next == 0) {
buffer->next = next_pos;
if (pwrite(fd, buffer, sizeof(struct keydb_node), pos) == -1) {
perror("pwrite() failed in keydb_insert.");
free(buffer);
return -1;
}
bzero(buffer, sizeof(struct keydb_node));
strcpy(buffer->column, column);
buffer->refcount = 1;
buffer->pos = next_pos;
if (pwrite(fd, buffer, sizeof(struct keydb_node), next_pos) == -1) {
perror("pwrite() failed in keydb_insert.");
free(buffer);
return -1;
}
free(buffer);
return next_pos;
return(new_subkey_tree(fd, column, pos, buffer));
} else { // insert our node in the tree that next points to. We're
// adding a subkey to an existing tree. Calling ourself with
@ -362,7 +366,7 @@ int find_free_key_node(int fd) {
} else {
//extend the file by one buffer length.
if (pwrite(fd, &buffer, sizeof(buffer), pos) == -1) {
perror("pwrite() failed in keydb_insert.");
perror("pwrite() failed in find_free_key_node.");
return -1;
}
return pos;