diff --git a/fist/hashmap.c b/fist/hashmap.c index 6f39e8d..6125033 100644 --- a/fist/hashmap.c +++ b/fist/hashmap.c @@ -4,8 +4,6 @@ #include #include -#define HMAP_SIZE 1000081 - unsigned int hash(char *val) { unsigned long sum = 0; for(int x = 0; x < strlen(val); x++) { diff --git a/fist/indexer.c b/fist/indexer.c index aae5615..50cb172 100644 --- a/fist/indexer.c +++ b/fist/indexer.c @@ -15,7 +15,7 @@ dstringa indexer(dstring text, int max_phrase_length) { for(int j = i; j < i + max_phrase_length; j++) { for(int k = 0; k < MIN(words.length - j, max_phrase_length); k++) { dstringa range = drange(words, j, j + k); - dstring joined = djoin(range, ' '); + dstring joined = dtrim(djoin(range, ' ')); index = dpush(index, joined); dfreea(range); dfree(joined); diff --git a/fist/server.c b/fist/server.c index 99df51f..752300c 100644 --- a/fist/server.c +++ b/fist/server.c @@ -29,6 +29,18 @@ #define NOT_FOUND "[]\n" #define TOO_FEW_ARGUMENTS "Too few arguments\n" #define DELETED "Key Removed\n" +#define NOT_IMPLEMENTED "Not Implemented\n" +#define NO_KEYS "No keys found\n" +#define DOCUMENT_DROPPED "Document dropped\n" +#define HELP \ + "INDEX -> Maps full-text indices to a value \n\ +\ +SEARCH -> Returns a document matching \n\ +KEYS -> Returns list of keys available for searching\n\ +DELETE -> Deletes a key\n\ +DROP -> Removes all references to a document. If a key is mapped only to then DROP will remove that key\n\ +HELP -> Shows this prompt\n\ +EXIT -> Close connection to Fist server\n" typedef int (*command_handler_t)(struct config *config, hashmap *hm, int fd, dstringa params); @@ -44,7 +56,70 @@ struct connection_info dstring last_command; }; -static int do_delete(hashmap *hm, int fd, dstringa params) { +static int do_help(struct config *config, hashmap *hm, int fd, dstringa params) { + send(fd, HELP, strlen(HELP), 0); + return 0; +} + +static int do_keys(struct config *config, hashmap *hm, int fd, dstringa params) { + dstring response = dempty(); + for(int i = 0; i < HMAP_SIZE; i++) { + hashmap on = hm[i]; + if(on.length) { + for(int j = 0; j < on.length; j++) { + keyval kv = on.maps[j]; + response = dappendc(dappendd(response, kv.key), '\n'); + } + } + } + + if(response.length == 0) { + send(fd, NO_KEYS, strlen(NO_KEYS), 0); + } else { + send(fd, dtext(response), response.length, 0); + } + + return 0; +} + +static int do_drop(struct config *config, hashmap *hm, int fd, dstringa params) { + if(params.length < 2) { + send(fd, TOO_FEW_ARGUMENTS, strlen(TOO_FEW_ARGUMENTS), 0); + return 0; + } + + dstring key = params.values[1]; + + for(int i = 0; i < HMAP_SIZE; i++) { + hashmap hmon = hm[i]; + if(hmon.length > 0) { + for(int j = 0; j < hmon.length; j++) { + keyval kv = hmon.maps[j]; + if(kv.values.length == 1) { + dstring value = kv.values.values[0]; + if(dequals(value, key)) { + hdel(hm, kv.key); + } + } else { + dstringa values = dcreatea(); + for(int k = 0; k < kv.values.length; k++) { + dstring value = kv.values.values[k]; + if(!dequals(value, key)) { + values = dpush(values, value); + } + } + hmon.maps[j].values = values; + } + } + } + } + + send(fd, DOCUMENT_DROPPED, strlen(DOCUMENT_DROPPED), 0); + + return 0; +} + +static int do_delete(struct config *config, hashmap *hm, int fd, dstringa params) { if(params.length < 2) { send(fd, TOO_FEW_ARGUMENTS, strlen(TOO_FEW_ARGUMENTS), 0); return 0; @@ -63,7 +138,7 @@ static int do_delete(hashmap *hm, int fd, dstringa params) { return 0; } -static int do_exit(hashmap *hm, int fd, dstringa params) { +static int do_exit(struct config *config, hashmap *hm, int fd, dstringa params) { send(fd, BYE, strlen(BYE), 0); return 1; } @@ -128,7 +203,6 @@ static int process_command(struct config *config, hashmap *hm, int fd, dstring r trimmed = dtrim(req); commands = dsplit(trimmed, ' '); printf("%d '%s'\n", req.length, dtext(trimmed)); - handler = (command_handler_t)bst_search(command_tree, dtext(commands.values[0])); if(!handler) { send(fd, INVALID_COMMAND, strlen(INVALID_COMMAND), 0); @@ -180,11 +254,14 @@ int start_server(struct config *config) { command_tree = NULL; // not a self balancing tree, be mindful of the order + bst_insert(&command_tree, "HELP", do_help); + bst_insert(&command_tree, "KEYS", do_keys); bst_insert(&command_tree, "INDEX", do_index); bst_insert(&command_tree, "EXIT", do_exit); bst_insert(&command_tree, "SEARCH", do_search); bst_insert(&command_tree, "DELETE", do_delete); bst_insert(&command_tree, "VERSION", do_version); + bst_insert(&command_tree, "DROP", do_drop); dtablesize = getdtablesize(); connection_infos = calloc(dtablesize, sizeof(struct connection_info));