comparison src/c/urweb.c @ 2250:c275bbc41194

Start work on pure expression caching.
author Ziv Scully <ziv@mit.edu>
date Sun, 13 Sep 2015 16:02:45 -0400
parents c05851bf7861
children 34ad83d9b729
comparison
equal deleted inserted replaced
2249:c05851bf7861 2250:c275bbc41194
4496 } 4496 }
4497 4497
4498 4498
4499 // Sqlcache 4499 // Sqlcache
4500 4500
4501 void uw_sqlcache_listDelete(uw_sqlcache_CacheList *list, uw_sqlcache_CacheEntry *entry) { 4501 void uw_Sqlcache_listDelete(uw_Sqlcache_CacheList *list, uw_Sqlcache_CacheEntry *entry) {
4502 if (list->first == entry) { 4502 if (list->first == entry) {
4503 list->first = entry->next; 4503 list->first = entry->next;
4504 } 4504 }
4505 if (list->last == entry) { 4505 if (list->last == entry) {
4506 list->last = entry->prev; 4506 list->last = entry->prev;
4514 entry->prev = NULL; 4514 entry->prev = NULL;
4515 entry->next = NULL; 4515 entry->next = NULL;
4516 --(list->size); 4516 --(list->size);
4517 } 4517 }
4518 4518
4519 void uw_sqlcache_listAdd(uw_sqlcache_CacheList *list, uw_sqlcache_CacheEntry *entry) { 4519 void uw_Sqlcache_listAdd(uw_Sqlcache_CacheList *list, uw_Sqlcache_CacheEntry *entry) {
4520 if (list->last) { 4520 if (list->last) {
4521 list->last->next = entry; 4521 list->last->next = entry;
4522 entry->prev = list->last; 4522 entry->prev = list->last;
4523 list->last = entry; 4523 list->last = entry;
4524 } else { 4524 } else {
4526 list->last = entry; 4526 list->last = entry;
4527 } 4527 }
4528 ++(list->size); 4528 ++(list->size);
4529 } 4529 }
4530 4530
4531 void uw_sqlcache_listBump(uw_sqlcache_CacheList *list, uw_sqlcache_CacheEntry *entry) { 4531 void uw_Sqlcache_listBump(uw_Sqlcache_CacheList *list, uw_Sqlcache_CacheEntry *entry) {
4532 uw_sqlcache_listDelete(list, entry); 4532 uw_Sqlcache_listDelete(list, entry);
4533 uw_sqlcache_listAdd(list, entry); 4533 uw_Sqlcache_listAdd(list, entry);
4534 } 4534 }
4535 4535
4536 // TODO: deal with time properly. 4536 // TODO: deal with time properly.
4537 4537
4538 time_t uw_sqlcache_getTimeNow() { 4538 time_t uw_Sqlcache_getTimeNow() {
4539 return time(NULL); 4539 return time(NULL);
4540 } 4540 }
4541 4541
4542 time_t uw_sqlcache_timeMax(time_t x, time_t y) { 4542 time_t uw_Sqlcache_timeMax(time_t x, time_t y) {
4543 return difftime(x, y) > 0 ? x : y; 4543 return difftime(x, y) > 0 ? x : y;
4544 } 4544 }
4545 4545
4546 void uw_sqlcache_freeuw_sqlcache_CacheValue(uw_sqlcache_CacheValue *value) { 4546 void uw_Sqlcache_freeuw_Sqlcache_CacheValue(uw_Sqlcache_CacheValue *value) {
4547 if (value) { 4547 if (value) {
4548 free(value->result); 4548 free(value->result);
4549 free(value->output); 4549 free(value->output);
4550 free(value); 4550 free(value);
4551 } 4551 }
4552 } 4552 }
4553 4553
4554 void uw_sqlcache_delete(uw_sqlcache_Cache *cache, uw_sqlcache_CacheEntry* entry) { 4554 void uw_Sqlcache_delete(uw_Sqlcache_Cache *cache, uw_Sqlcache_CacheEntry* entry) {
4555 //uw_sqlcache_listUw_Sqlcache_Delete(cache->lru, entry); 4555 //uw_Sqlcache_listUw_Sqlcache_Delete(cache->lru, entry);
4556 HASH_DELETE(hh, cache->table, entry); 4556 HASH_DELETE(hh, cache->table, entry);
4557 uw_sqlcache_freeuw_sqlcache_CacheValue(entry->value); 4557 uw_Sqlcache_freeuw_Sqlcache_CacheValue(entry->value);
4558 free(entry->key); 4558 free(entry->key);
4559 free(entry); 4559 free(entry);
4560 } 4560 }
4561 4561
4562 uw_sqlcache_CacheValue *uw_sqlcache_checkHelper(uw_sqlcache_Cache *cache, char **keys, int timeInvalid) { 4562 uw_Sqlcache_CacheValue *uw_Sqlcache_checkHelper(uw_Sqlcache_Cache *cache, char **keys, int timeInvalid) {
4563 char *key = keys[cache->height]; 4563 char *key = keys[cache->height];
4564 uw_sqlcache_CacheEntry *entry; 4564 uw_Sqlcache_CacheEntry *entry;
4565 HASH_FIND(hh, cache->table, key, strlen(key), entry); 4565 HASH_FIND(hh, cache->table, key, strlen(key), entry);
4566 timeInvalid = uw_sqlcache_timeMax(timeInvalid, cache->timeInvalid); 4566 timeInvalid = uw_Sqlcache_timeMax(timeInvalid, cache->timeInvalid);
4567 if (entry && difftime(entry->timeValid, timeInvalid) > 0) { 4567 if (entry && difftime(entry->timeValid, timeInvalid) > 0) {
4568 if (cache->height == 0) { 4568 if (cache->height == 0) {
4569 // At height 0, entry->value is the desired value. 4569 // At height 0, entry->value is the desired value.
4570 //uw_sqlcache_listBump(cache->lru, entry); 4570 //uw_Sqlcache_listBump(cache->lru, entry);
4571 return entry->value; 4571 return entry->value;
4572 } else { 4572 } else {
4573 // At height n+1, entry->value is a pointer to a cache at heignt n. 4573 // At height n+1, entry->value is a pointer to a cache at heignt n.
4574 return uw_sqlcache_checkHelper(entry->value, keys, timeInvalid); 4574 return uw_Sqlcache_checkHelper(entry->value, keys, timeInvalid);
4575 } 4575 }
4576 } else { 4576 } else {
4577 return NULL; 4577 return NULL;
4578 } 4578 }
4579 } 4579 }
4580 4580
4581 uw_sqlcache_CacheValue *uw_sqlcache_check(uw_sqlcache_Cache *cache, char **keys) { 4581 uw_Sqlcache_CacheValue *uw_Sqlcache_check(uw_Sqlcache_Cache *cache, char **keys) {
4582 return uw_sqlcache_checkHelper(cache, keys, 0); 4582 return uw_Sqlcache_checkHelper(cache, keys, 0);
4583 } 4583 }
4584 4584
4585 void uw_sqlcache_storeHelper(uw_sqlcache_Cache *cache, char **keys, uw_sqlcache_CacheValue *value, int timeNow) { 4585 void uw_Sqlcache_storeHelper(uw_Sqlcache_Cache *cache, char **keys, uw_Sqlcache_CacheValue *value, int timeNow) {
4586 uw_sqlcache_CacheEntry *entry; 4586 uw_Sqlcache_CacheEntry *entry;
4587 char *key = keys[cache->height]; 4587 char *key = keys[cache->height];
4588 HASH_FIND(hh, cache->table, key, strlen(key), entry); 4588 HASH_FIND(hh, cache->table, key, strlen(key), entry);
4589 if (!entry) { 4589 if (!entry) {
4590 entry = malloc(sizeof(uw_sqlcache_CacheEntry)); 4590 entry = malloc(sizeof(uw_Sqlcache_CacheEntry));
4591 entry->key = strdup(key); 4591 entry->key = strdup(key);
4592 entry->value = NULL; 4592 entry->value = NULL;
4593 HASH_ADD_KEYPTR(hh, cache->table, entry->key, strlen(entry->key), entry); 4593 HASH_ADD_KEYPTR(hh, cache->table, entry->key, strlen(entry->key), entry);
4594 } 4594 }
4595 entry->timeValid = timeNow; 4595 entry->timeValid = timeNow;
4596 if (cache->height == 0) { 4596 if (cache->height == 0) {
4597 //uw_sqlcache_listAdd(cache->lru, entry); 4597 //uw_Sqlcache_listAdd(cache->lru, entry);
4598 uw_sqlcache_freeuw_sqlcache_CacheValue(entry->value); 4598 uw_Sqlcache_freeuw_Sqlcache_CacheValue(entry->value);
4599 entry->value = value; 4599 entry->value = value;
4600 //if (cache->lru->size > MAX_SIZE) { 4600 //if (cache->lru->size > MAX_SIZE) {
4601 //uw_sqlcache_delete(cache, cache->lru->first); 4601 //uw_Sqlcache_delete(cache, cache->lru->first);
4602 // TODO: return flushed value. 4602 // TODO: return flushed value.
4603 //} 4603 //}
4604 } else { 4604 } else {
4605 if (!entry->value) { 4605 if (!entry->value) {
4606 uw_sqlcache_Cache *newuw_sqlcache_Cache = malloc(sizeof(uw_sqlcache_Cache)); 4606 uw_Sqlcache_Cache *newuw_Sqlcache_Cache = malloc(sizeof(uw_Sqlcache_Cache));
4607 newuw_sqlcache_Cache->table = NULL; 4607 newuw_Sqlcache_Cache->table = NULL;
4608 newuw_sqlcache_Cache->timeInvalid = timeNow; 4608 newuw_Sqlcache_Cache->timeInvalid = timeNow;
4609 newuw_sqlcache_Cache->lru = cache->lru; 4609 newuw_Sqlcache_Cache->lru = cache->lru;
4610 newuw_sqlcache_Cache->height = cache->height - 1; 4610 newuw_Sqlcache_Cache->height = cache->height - 1;
4611 entry->value = newuw_sqlcache_Cache; 4611 entry->value = newuw_Sqlcache_Cache;
4612 } 4612 }
4613 uw_sqlcache_storeHelper(entry->value, keys, value, timeNow); 4613 uw_Sqlcache_storeHelper(entry->value, keys, value, timeNow);
4614 } 4614 }
4615 } 4615 }
4616 4616
4617 void uw_sqlcache_store(uw_sqlcache_Cache *cache, char **keys, uw_sqlcache_CacheValue *value) { 4617 void uw_Sqlcache_store(uw_Sqlcache_Cache *cache, char **keys, uw_Sqlcache_CacheValue *value) {
4618 uw_sqlcache_storeHelper(cache, keys, value, uw_sqlcache_getTimeNow()); 4618 uw_Sqlcache_storeHelper(cache, keys, value, uw_Sqlcache_getTimeNow());
4619 } 4619 }
4620 4620
4621 void uw_sqlcache_flushHelper(uw_sqlcache_Cache *cache, char **keys, int timeNow) { 4621 void uw_Sqlcache_flushHelper(uw_Sqlcache_Cache *cache, char **keys, int timeNow) {
4622 uw_sqlcache_CacheEntry *entry; 4622 uw_Sqlcache_CacheEntry *entry;
4623 char *key = keys[cache->height]; 4623 char *key = keys[cache->height];
4624 if (key) { 4624 if (key) {
4625 HASH_FIND(hh, cache->table, key, strlen(key), entry); 4625 HASH_FIND(hh, cache->table, key, strlen(key), entry);
4626 if (entry) { 4626 if (entry) {
4627 if (cache->height == 0) { 4627 if (cache->height == 0) {
4628 uw_sqlcache_delete(cache, entry); 4628 uw_Sqlcache_delete(cache, entry);
4629 } else { 4629 } else {
4630 uw_sqlcache_flushHelper(entry->value, keys, timeNow); 4630 uw_Sqlcache_flushHelper(entry->value, keys, timeNow);
4631 } 4631 }
4632 } 4632 }
4633 } else { 4633 } else {
4634 // Null key means invalidate the entire subtree. 4634 // Null key means invalidate the entire subtree.
4635 cache->timeInvalid = timeNow; 4635 cache->timeInvalid = timeNow;
4636 } 4636 }
4637 } 4637 }
4638 4638
4639 void uw_sqlcache_flush(uw_sqlcache_Cache *cache, char **keys) { 4639 void uw_Sqlcache_flush(uw_Sqlcache_Cache *cache, char **keys) {
4640 uw_sqlcache_flushHelper(cache, keys, uw_sqlcache_getTimeNow()); 4640 uw_Sqlcache_flushHelper(cache, keys, uw_Sqlcache_getTimeNow());
4641 } 4641 }