Mercurial > urweb
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 } |