static int fqd_http_message_header_value(http_parser *p, const char *at, size_t len) { struct http_req *req = p->data; ck_ht_entry_t entry; ck_ht_hash_t hv; char *val; if(!req->fldname) return -1; val = malloc(len+1); strlcpy(val, at, len+1); fq_debug(FQ_DEBUG_HTTP, ".on_header_value -> '%s'\n", val); ck_ht_hash(&hv, &req->headers, req->fldname, strlen(req->fldname)); ck_ht_entry_set(&entry, hv, req->fldname, strlen(req->fldname), val); if(ck_ht_set_spmc(&req->headers, hv, &entry) && !ck_ht_entry_empty(&entry)) { char *key = ck_ht_entry_key(&entry); char *value = ck_ht_entry_value(&entry); if(key && key != req->fldname) free(key); if(value && value != val) free(value); } if(!strcmp(req->fldname, "expect") && !strcasecmp(val,"100-continue")) req->expect_continue = HTTP_EXPECT_CONTINUE; req->fldname = NULL; return 0; }
static void http_req_clean(struct http_req *req) { ck_ht_entry_t *cursor; ck_ht_iterator_t iterator = CK_HT_ITERATOR_INITIALIZER; while(ck_ht_next(&req->headers, &iterator, &cursor)) { ck_ht_hash_t hv; char *key = ck_ht_entry_key(cursor); char *value = ck_ht_entry_value(cursor); ck_ht_hash(&hv, &req->headers, key, strlen(key)); ck_ht_remove_spmc(&req->headers, hv, cursor); free(key); free(value); } ck_ht_iterator_init(&iterator); while(ck_ht_next(&req->query_params, &iterator, &cursor)) { ck_ht_hash_t hv; char *key = ck_ht_entry_key(cursor); char *value = ck_ht_entry_value(cursor); ck_ht_hash(&hv, &req->headers, key, strlen(key)); ck_ht_remove_spmc(&req->headers, hv, cursor); free(key); free(value); } if(req->url) free(req->url); /* req->qs isn't allocated */ if(req->status) free(req->status); if(req->fldname) free(req->fldname); if(req->error) free(req->error); if(req->msg) fq_msg_deref(req->msg); req->url = NULL; req->qs = NULL; req->status = NULL; req->fldname = NULL; req->error = NULL; req->body_len = 0; req->body_read = 0; req->msg = NULL; req->expect_continue = HTTP_EXPECT_NONE; }
static char* __remove_stored_etag(const kstr_t* key) { ck_ht_hash_t hash; ck_ht_entry_t entry; ck_ht_entry_key_set(&entry, key->s, key->len); ck_ht_hash(&hash, &sv->etags, key->s, key->len); int e = ck_ht_remove_spmc(&sv->etags, hash, &entry); if (1 == e) return ck_ht_entry_value(&entry); return NULL; }
void brubeck_hashtable_foreach(brubeck_hashtable_t *ht, void (*callback)(struct brubeck_metric *, void *), void *payload) { ck_ht_iterator_t iterator = CK_HT_ITERATOR_INITIALIZER; ck_ht_entry_t *entry; pthread_mutex_lock(&ht->write_mutex); while (ck_ht_next(&ht->table, &iterator, &entry)) callback(ck_ht_entry_value(entry), payload); pthread_mutex_unlock(&ht->write_mutex); }
static const char * fqd_http_header(struct http_req *req, const char *hdr) { ck_ht_entry_t entry; ck_ht_hash_t hv; int hdrlen = strlen(hdr); ck_ht_hash(&hv, &req->headers, hdr, hdrlen); ck_ht_entry_set(&entry, hv, hdr, hdrlen, NULL); if(ck_ht_get_spmc(&req->headers, hv, &entry)) { return ck_ht_entry_value(&entry); } return NULL; }
static const char * get_ht_value(ck_ht_t *table, const char *key) { ck_ht_entry_t entry; ck_ht_hash_t hv; ck_ht_hash(&hv, table, key, strlen(key)); ck_ht_entry_key_set(&entry, key, strlen(key)); if (ck_ht_get_spmc(table, hv, &entry)) { return ck_ht_entry_value(&entry); } return NULL; }
struct brubeck_metric * brubeck_hashtable_find(brubeck_hashtable_t *ht, const char *key, uint16_t key_len) { ck_ht_hash_t h; ck_ht_entry_t entry; ck_ht_hash(&h, &ht->table, key, key_len); ck_ht_entry_key_set(&entry, key, key_len); if (ck_ht_get_spmc(&ht->table, h, &entry)) return ck_ht_entry_value(&entry); return NULL; }
static void * table_get(const char *value) { ck_ht_entry_t entry; ck_ht_hash_t h; size_t l = strlen(value); ck_ht_hash(&h, &ht, value, l); ck_ht_entry_key_set(&entry, value, l); if (ck_ht_get_spmc(&ht, h, &entry) == true) return ck_ht_entry_value(&entry); return NULL; }
static int __get_or_create_etag(const kstr_t* key, const MDB_val *val, h2o_iovec_t *etagvec) { int e; ck_ht_hash_t hash; ck_ht_entry_t entry; char* etag = NULL; ck_ht_hash(&hash, &sv->etags, key->s, key->len); ck_ht_entry_key_set(&entry, key->s, key->len); do { e = ck_ht_get_spmc(&sv->etags, hash, &entry); if (0 == e) { uv_mutex_lock(&sv->etag_lock); int num = sv->etag_num; sv->etag_num++; uv_mutex_unlock(&sv->etag_lock); /* TODO: get this memory from a pool */ etag = malloc(ETAG_LEN); if (!etag) goto fail; snprintf(etag, ETAG_LEN + 1, "%8.8d%20.20d", sv->etag_prefix, num); char* my_key = strndup(key->s, key->len); if (!my_key) goto fail; ck_ht_entry_set(&entry, hash, my_key, key->len, etag); /* CK doesn't support multiple writers */ uv_mutex_lock(&sv->etag_lock); e = ck_ht_put_spmc(&sv->etags, hash, &entry); uv_mutex_unlock(&sv->etag_lock); } } while (e == 0); etagvec->base = ck_ht_entry_value(&entry); etagvec->len = ETAG_LEN; return 0; fail: if (etag) free(etag); return -1; }
int main(void) { size_t i, l; ck_ht_t ht; ck_ht_entry_t entry; ck_ht_hash_t h; ck_ht_iterator_t iterator = CK_HT_ITERATOR_INITIALIZER; ck_ht_entry_t *cursor; if (ck_ht_init(&ht, CK_HT_MODE_BYTESTRING, NULL, &my_allocator, 8, 6602834) == false) { perror("ck_ht_init"); exit(EXIT_FAILURE); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, test[i]); ck_ht_put_spmc(&ht, h, &entry); } l = strlen(test[0]); ck_ht_hash(&h, &ht, test[0], l); ck_ht_entry_set(&entry, h, test[0], l, test[0]); ck_ht_put_spmc(&ht, h, &entry); for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) { ck_error("ERROR (put): Failed to find [%s]\n", test[i]); } else { void *k, *v; k = ck_ht_entry_key(&entry); v = ck_ht_entry_value(&entry); if (strcmp(k, test[i]) || strcmp(v, test[i])) { ck_error("ERROR: Mismatch: (%s, %s) != (%s, %s)\n", (char *)k, (char *)v, test[i], test[i]); } } } ck_ht_hash(&h, &ht, negative, strlen(negative)); ck_ht_entry_key_set(&entry, negative, strlen(negative)); if (ck_ht_get_spmc(&ht, h, &entry) == true) { ck_error("ERROR: Found non-existing entry.\n"); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) continue; if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } if (ck_ht_get_spmc(&ht, h, &entry) == true) ck_error("ERROR: Able to find [%s] after delete\n", test[i]); ck_ht_entry_set(&entry, h, test[i], l, test[i]); if (ck_ht_put_spmc(&ht, h, &entry) == false) ck_error("ERROR: Failed to insert [%s]\n", test[i]); if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } } ck_ht_reset_spmc(&ht); if (ck_ht_count(&ht) != 0) { ck_error("ERROR: Map was not reset.\n"); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, test[i]); ck_ht_put_spmc(&ht, h, &entry); } for (i = 0; ck_ht_next(&ht, &iterator, &cursor) == true; i++); if (i != 42) { ck_error("ERROR: Incorrect number of entries in table.\n"); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, test[i]); ck_ht_set_spmc(&ht, h, &entry); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) { ck_error("ERROR (set): Failed to find [%s]\n", test[i]); } else { void *k, *v; k = ck_ht_entry_key(&entry); v = ck_ht_entry_value(&entry); if (strcmp(k, test[i]) || strcmp(v, test[i])) { ck_error("ERROR: Mismatch: (%s, %s) != (%s, %s)\n", (char *)k, (char *)v, test[i], test[i]); } } } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, "REPLACED"); ck_ht_set_spmc(&ht, h, &entry); if (strcmp(test[i], "What") == 0) continue; if (strcmp(test[i], "down.") == 0) continue; if (strcmp(ck_ht_entry_value(&entry), test[i]) != 0) { ck_error("Mismatch detected: %s, expected %s\n", (char *)ck_ht_entry_value(&entry), test[i]); } } ck_ht_iterator_init(&iterator); while (ck_ht_next(&ht, &iterator, &cursor) == true) { if (strcmp(ck_ht_entry_value(cursor), "REPLACED") != 0) { ck_error("Mismatch detected: %s, expected REPLACED\n", (char *)ck_ht_entry_value(cursor)); } } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) continue; if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } if (ck_ht_get_spmc(&ht, h, &entry) == true) ck_error("ERROR: Able to find [%s] after delete\n", test[i]); ck_ht_entry_set(&entry, h, test[i], l, test[i]); if (ck_ht_put_spmc(&ht, h, &entry) == false) ck_error("ERROR: Failed to insert [%s]\n", test[i]); if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } } ck_ht_destroy(&ht); if (ck_ht_init(&ht, CK_HT_MODE_DIRECT, NULL, &my_allocator, 8, 6602834) == false) { perror("ck_ht_init"); exit(EXIT_FAILURE); } l = 0; for (i = 0; i < sizeof(direct) / sizeof(*direct); i++) { ck_ht_hash_direct(&h, &ht, direct[i]); ck_ht_entry_set_direct(&entry, h, direct[i], (uintptr_t)test[i]); l += ck_ht_put_spmc(&ht, h, &entry) == false; } if (l != 7) { ck_error("ERROR: Got %zu failures rather than 7\n", l); } for (i = 0; i < sizeof(direct) / sizeof(*direct); i++) { ck_ht_hash_direct(&h, &ht, direct[i]); ck_ht_entry_set_direct(&entry, h, direct[i], (uintptr_t)"REPLACED"); l += ck_ht_set_spmc(&ht, h, &entry) == false; } ck_ht_iterator_init(&iterator); while (ck_ht_next(&ht, &iterator, &cursor) == true) { if (strcmp(ck_ht_entry_value(cursor), "REPLACED") != 0) { ck_error("Mismatch detected: %s, expected REPLACED\n", (char *)ck_ht_entry_value(cursor)); } } ck_ht_destroy(&ht); return 0; }