#ifndef FAST_CACHE_HANDLERS #define FAST_CACHE_HANDLERS #include #include "common.c" #include "queue.c" void handle_stats(KCLIST* tokens, FILE* client){ char out[1024]; float hit_ratio = 0; if(hits){ hit_ratio = (float)hits / (float)(hits + misses); } char* status = kcdbstatus(db); KCLIST* stats = kclistnew(); tokenize(stats, status, "\n"); char status_buf[1024]; strcpy(status_buf, ""); int stat_count = kclistcount(stats); int i; for(i = 0; i < stat_count; ++i){ size_t part_size; const char* part = kclistget(stats, i, &part_size); KCLIST* parts = kclistnew(); tokenize(parts, (char*)part, "\t"); char buf[128]; if(kclistcount(parts) == 2){ sprintf(buf, "STAT %s %s\r\n", kclistget(parts, 0, &part_size), kclistget(parts, 1, &part_size)); } kclistdel(parts); strcat(status_buf, buf); } sprintf(out, STATS_FORMAT, connections, hits, misses, hit_ratio, status_buf); fputs(out, client); } void handle_version(KCLIST* tokens, FILE* client){ char out[1024]; sprintf(out, "VERSION %s\r\n", VERSION); fputs(out, client); } void handle_flush(KCLIST* tokens, FILE* client){ if(kcdbclear(db)){ fputs("OK\r\n", client); } } void handle_delete(KCLIST* tokens, FILE* client){ if(kclistcount(tokens)){ char key[128]; list_shift(tokens, key); if(kcdbremove(db, key, strlen(key))){ fputs("DELETED\r\n", client); } } } void handle_get(KCLIST* tokens, FILE* client){ if(kclistcount(tokens)){ char key[128]; list_shift(tokens, key); char out[1024]; char* result_buffer; size_t result_size; result_buffer = kcdbget(db, key, strlen(key), &result_size); if(result_buffer){ if(strcmp(result_buffer, "0") == 0){ ++misses; sprintf(out, "VALUE %s 0 2\r\n{}\r\nEND\r\n", key); } else{ ++hits; sprintf(out, "VALUE %s 0 %d\r\n%s\r\nEND\r\n", key, (int)strlen(result_buffer), result_buffer); } kcfree(result_buffer); } else{ ++misses; sprintf(out, "VALUE %s 0 2\r\n{}\r\nEND\r\n", key); kcdbset(db, key, strlen(key), "0", 1); queue_add(&requests, key); } fputs(out, client); } else{ fputs("INVALID GET COMMAND: GET \r\n", client); return; } } int handle_command(char* buffer, FILE* client){ int status = 0; char command[1024]; KCLIST* tokens = kclistnew(); tokenize(tokens, buffer, " "); list_shift(tokens, command); if(command){ if(strcmp(command, "get") == 0){ handle_get(tokens, client); } else if(strcmp(command, "stats") == 0){ handle_stats(tokens, client); } else if(strcmp(command, "flush_all") == 0){ handle_flush(tokens, client); } else if(strcmp(command, "delete") == 0){ handle_delete(tokens, client); } else if(strcmp(command, "version") == 0){ handle_version(tokens, client); } else if(strcmp(command, "quit") == 0){ status = -1; } else{ char out[1024]; sprintf(out, "UNKNOWN COMMAND: %s\r\n", command); fputs(out, client); } } kclistdel(tokens); return status; } #endif