comparison src/c/urweb.c @ 2284:472b4504aef2

Actually use transactional machinery for flushes this time.
author Ziv Scully <ziv@mit.edu>
date Thu, 12 Nov 2015 11:44:21 -0500
parents 4afaab523213
children ad3ce1528f71
comparison
equal deleted inserted replaced
2283:4afaab523213 2284:472b4504aef2
4543 } 4543 }
4544 4544
4545 4545
4546 // Sqlcache 4546 // Sqlcache
4547 4547
4548 typedef struct uw_Sqlcache_Entry {
4549 char *key;
4550 uw_Sqlcache_Value *value;
4551 unsigned long timeInvalid;
4552 UT_hash_handle hh;
4553 } uw_Sqlcache_Entry;
4554
4548 void uw_Sqlcache_freeValue(uw_Sqlcache_Value *value) { 4555 void uw_Sqlcache_freeValue(uw_Sqlcache_Value *value) {
4549 if (value) { 4556 if (value) {
4550 free(value->result); 4557 free(value->result);
4551 free(value->output); 4558 free(value->output);
4552 free(value); 4559 free(value);
4597 return x > y ? x : y; 4604 return x > y ? x : y;
4598 } 4605 }
4599 4606
4600 char uw_Sqlcache_keySep = '_'; 4607 char uw_Sqlcache_keySep = '_';
4601 4608
4602 char *uw_Sqlcache_allocKeyBuffer(char **keys, int numKeys) { 4609 char *uw_Sqlcache_allocKeyBuffer(char **keys, size_t numKeys) {
4603 size_t len = 0; 4610 size_t len = 0;
4604 while (numKeys-- > 0) { 4611 while (numKeys-- > 0) {
4605 char* k = keys[numKeys]; 4612 char* k = keys[numKeys];
4606 if (!k) { 4613 if (!k) {
4607 // Can only happen when flushihg, in which case we don't need anything past the null key. 4614 // Can only happen when flushihg, in which case we don't need anything past the null key.
4623 4630
4624 // The NUL-terminated prefix of [key] below always looks something like "_k1_k2_k3..._kn". 4631 // The NUL-terminated prefix of [key] below always looks something like "_k1_k2_k3..._kn".
4625 // TODO: strlen(key) = buf - key? 4632 // TODO: strlen(key) = buf - key?
4626 4633
4627 uw_Sqlcache_Value *uw_Sqlcache_check(uw_Sqlcache_Cache *cache, char **keys) { 4634 uw_Sqlcache_Value *uw_Sqlcache_check(uw_Sqlcache_Cache *cache, char **keys) {
4635 //pthread_rwlock_rdlock(cache->lock);
4628 size_t numKeys = cache->numKeys; 4636 size_t numKeys = cache->numKeys;
4629 char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys); 4637 char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys);
4630 char *buf = key; 4638 char *buf = key;
4631 time_t timeInvalid = cache->timeInvalid; 4639 time_t timeInvalid = cache->timeInvalid;
4632 uw_Sqlcache_Entry *entry; 4640 uw_Sqlcache_Entry *entry;
4640 } 4648 }
4641 timeInvalid = uw_Sqlcache_timeMax(timeInvalid, entry->timeInvalid); 4649 timeInvalid = uw_Sqlcache_timeMax(timeInvalid, entry->timeInvalid);
4642 } 4650 }
4643 free(key); 4651 free(key);
4644 uw_Sqlcache_Value *value = entry->value; 4652 uw_Sqlcache_Value *value = entry->value;
4653 //pthread_rwlock_unlock(cache->lock);
4645 return value && value->timeValid > timeInvalid ? value : NULL; 4654 return value && value->timeValid > timeInvalid ? value : NULL;
4646 } 4655 }
4647 4656
4648 void uw_Sqlcache_store(uw_Sqlcache_Cache *cache, char **keys, uw_Sqlcache_Value *value) { 4657 void uw_Sqlcache_store(uw_Sqlcache_Cache *cache, char **keys, uw_Sqlcache_Value *value) {
4658 //pthread_rwlock_wrlock(cache->lock);
4649 size_t numKeys = cache->numKeys; 4659 size_t numKeys = cache->numKeys;
4650 char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys); 4660 char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys);
4651 char *buf = key; 4661 char *buf = key;
4652 time_t timeNow = uw_Sqlcache_getTimeNow(cache); 4662 time_t timeNow = uw_Sqlcache_getTimeNow(cache);
4653 uw_Sqlcache_Entry *entry; 4663 uw_Sqlcache_Entry *entry;
4665 } 4675 }
4666 free(key); 4676 free(key);
4667 uw_Sqlcache_freeValue(entry->value); 4677 uw_Sqlcache_freeValue(entry->value);
4668 entry->value = value; 4678 entry->value = value;
4669 entry->value->timeValid = timeNow; 4679 entry->value->timeValid = timeNow;
4680 //pthread_rwlock_unlock(cache->lock);
4670 } 4681 }
4671 4682
4672 void uw_Sqlcache_flushCommitOne(uw_Sqlcache_Cache *cache, char **keys) { 4683 void uw_Sqlcache_flushCommitOne(uw_Sqlcache_Cache *cache, char **keys) {
4673 size_t numKeys = cache->numKeys; 4684 size_t numKeys = cache->numKeys;
4674 char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys); 4685 char *key = uw_Sqlcache_allocKeyBuffer(keys, numKeys);
4715 } 4726 }
4716 } 4727 }
4717 4728
4718 void uw_Sqlcache_flushCommit(void *data) { 4729 void uw_Sqlcache_flushCommit(void *data) {
4719 uw_Sqlcache_Inval *inval = (uw_Sqlcache_Inval *)data; 4730 uw_Sqlcache_Inval *inval = (uw_Sqlcache_Inval *)data;
4720 uw_Sqlcache_Inval *invalFirst = inval;
4721 while (inval) { 4731 while (inval) {
4722 uw_Sqlcache_Cache *cache = inval->cache; 4732 uw_Sqlcache_Cache *cache = inval->cache;
4723 char **keys = inval->keys; 4733 char **keys = inval->keys;
4724 uw_Sqlcache_flushCommitOne(cache, keys); 4734 uw_Sqlcache_flushCommitOne(cache, keys);
4725 inval = inval->next; 4735 inval = inval->next;
4726 } 4736 }
4727 uw_Sqlcache_flushFree(invalFirst, 0); 4737 }
4738
4739 char **uw_Sqlcache_copyKeys(char **keys, size_t numKeys) {
4740 char **copy = malloc(sizeof(char *) * numKeys);
4741 while (numKeys-- > 0) {
4742 char * k = keys[numKeys];
4743 copy[numKeys] = k ? strdup(k) : NULL;
4744 }
4745 return copy;
4728 } 4746 }
4729 4747
4730 void uw_Sqlcache_flush(uw_context ctx, uw_Sqlcache_Cache *cache, char **keys) { 4748 void uw_Sqlcache_flush(uw_context ctx, uw_Sqlcache_Cache *cache, char **keys) {
4749 //pthread_rwlock_wrlock(cache->lock);
4731 uw_Sqlcache_Inval *inval = malloc(sizeof(uw_Sqlcache_Inval)); 4750 uw_Sqlcache_Inval *inval = malloc(sizeof(uw_Sqlcache_Inval));
4732 inval->cache = cache; 4751 inval->cache = cache;
4733 inval->keys = keys; 4752 inval->keys = uw_Sqlcache_copyKeys(keys, cache->numKeys);
4734 inval->next = NULL; 4753 inval->next = NULL;
4735 if (ctx->inval) { 4754 if (ctx->inval) {
4736 // An invalidation is already registered, so just extend it. 4755 // An invalidation is already registered, so just extend it.
4737 ctx->inval->next = inval; 4756 ctx->inval->next = inval;
4738 } else { 4757 } else {
4739 uw_register_transactional(ctx, inval, uw_Sqlcache_flushCommit, NULL, uw_Sqlcache_flushFree); 4758 uw_register_transactional(ctx, inval, uw_Sqlcache_flushCommit, NULL, uw_Sqlcache_flushFree);
4740 } 4759 }
4741 // [ctx->inval] should always point to the last invalidation. 4760 // [ctx->inval] should always point to the last invalidation.
4742 ctx->inval = inval; 4761 ctx->inval = inval;
4743 } 4762 //pthread_rwlock_unlock(cache->lock);
4763 }