comparison src/c/urweb.c @ 2234:2f7ed04332a0

Progress on LRU cache but still more known bugs to fix.
author Ziv Scully <ziv@mit.edu>
date Sun, 28 Jun 2015 12:46:51 -0700
parents e10881cd92da
children 88cc0f44c940
comparison
equal deleted inserted replaced
2233:af1585e7d645 2234:2f7ed04332a0
19 #include <math.h> 19 #include <math.h>
20 20
21 #include <pthread.h> 21 #include <pthread.h>
22 22
23 #include "types.h" 23 #include "types.h"
24
25 #include "uthash.h"
24 26
25 uw_unit uw_unit_v = 0; 27 uw_unit uw_unit_v = 0;
26 28
27 29
28 // Socket extras 30 // Socket extras
4492 } 4494 }
4493 4495
4494 void uw_set_remoteSock(uw_context ctx, int sock) { 4496 void uw_set_remoteSock(uw_context ctx, int sock) {
4495 ctx->remoteSock = sock; 4497 ctx->remoteSock = sock;
4496 } 4498 }
4499
4500
4501 // Sqlcache
4502
4503 void listDelete(CacheList *list, CacheEntry *entry) {
4504 if (list->first == entry) {
4505 list->first = entry->next;
4506 }
4507 if (list->last == entry) {
4508 list->last = entry->prev;
4509 }
4510 if (entry->prev) {
4511 entry->prev->next = entry->next;
4512 }
4513 if (entry->next) {
4514 entry->next->prev = entry->prev;
4515 }
4516 entry->prev = NULL;
4517 entry->next = NULL;
4518 --(list->size);
4519 }
4520
4521 void listAdd(CacheList *list, CacheEntry *entry) {
4522 if (list->last) {
4523 list->last->next = entry;
4524 entry->prev = list->last;
4525 list->last = entry;
4526 } else {
4527 list->first = entry;
4528 list->last = entry;
4529 }
4530 ++(list->size);
4531 }
4532
4533 void listBump(CacheList *list, CacheEntry *entry) {
4534 listDelete(list, entry);
4535 listAdd(list, entry);
4536 }
4537
4538 // TODO: deal with time properly.
4539
4540 time_t getTimeNow() {
4541 return time(NULL);
4542 }
4543
4544 time_t timeMax(time_t x, time_t y) {
4545 return difftime(x, y) > 0 ? x : y;
4546 }
4547
4548 void freeCacheValue(CacheValue *value) {
4549 if (value) {
4550 free(value->result);
4551 free(value->output);
4552 free(value);
4553 }
4554 }
4555
4556 void delete(Cache *cache, CacheEntry* entry) {
4557 //listDelete(cache->lru, entry);
4558 HASH_DELETE(hh, cache->table, entry);
4559 freeCacheValue(entry->value);
4560 free(entry->key);
4561 free(entry);
4562 }
4563
4564 CacheValue *checkHelper(Cache *cache, char **keys, int timeInvalid) {
4565 char *key = keys[cache->height];
4566 CacheEntry *entry;
4567 HASH_FIND(hh, cache->table, key, strlen(key), entry);
4568 timeInvalid = timeMax(timeInvalid, cache->timeInvalid);
4569 if (entry && difftime(entry->timeValid, timeInvalid) > 0) {
4570 if (cache->height == 0) {
4571 // At height 0, entry->value is the desired value.
4572 //listBump(cache->lru, entry);
4573 return entry->value;
4574 } else {
4575 // At height n+1, entry->value is a pointer to a cache at heignt n.
4576 return checkHelper(entry->value, keys, timeInvalid);
4577 }
4578 } else {
4579 return NULL;
4580 }
4581 }
4582
4583 CacheValue *check(Cache *cache, char **keys) {
4584 return checkHelper(cache, keys, 0);
4585 }
4586
4587 void storeHelper(Cache *cache, char **keys, CacheValue *value, int timeNow) {
4588 CacheEntry *entry;
4589 char *key = keys[cache->height];
4590 HASH_FIND(hh, cache->table, key, strlen(key), entry);
4591 if (!entry) {
4592 entry = malloc(sizeof(CacheEntry));
4593 entry->key = strdup(key);
4594 entry->value = NULL;
4595 HASH_ADD_KEYPTR(hh, cache->table, entry->key, strlen(entry->key), entry);
4596 }
4597 entry->timeValid = timeNow;
4598 if (cache->height == 0) {
4599 //listAdd(cache->lru, entry);
4600 freeCacheValue(entry->value);
4601 entry->value = value;
4602 //if (cache->lru->size > MAX_SIZE) {
4603 //delete(cache, cache->lru->first);
4604 // TODO: return flushed value.
4605 //}
4606 } else {
4607 if (!entry->value) {
4608 Cache *newCache = malloc(sizeof(Cache));
4609 newCache->table = NULL;
4610 newCache->timeInvalid = timeNow;
4611 newCache->lru = cache->lru;
4612 newCache->height = cache->height - 1;
4613 entry->value = newCache;
4614 }
4615 storeHelper(entry->value, keys, value, timeNow);
4616 }
4617 }
4618
4619 void store(Cache *cache, char **keys, CacheValue *value) {
4620 storeHelper(cache, keys, value, getTimeNow());
4621 }
4622
4623 void flushHelper(Cache *cache, char **keys, int timeNow) {
4624 CacheEntry *entry;
4625 char *key = keys[cache->height];
4626 if (key) {
4627 HASH_FIND(hh, cache->table, key, strlen(key), entry);
4628 if (entry) {
4629 if (cache->height == 0) {
4630 delete(cache, entry);
4631 } else {
4632 flushHelper(entry->value, keys, timeNow);
4633 }
4634 }
4635 } else {
4636 // Null key means invalidate the entire subtree.
4637 cache->timeInvalid = timeNow;
4638 }
4639 }
4640
4641 void flush(Cache *cache, char **keys) {
4642 flushHelper(cache, keys, getTimeNow());
4643 }