/* Inserts the given KEY, VALUE pair into this server's store and cache. Access * to the cache should be concurrent if the keys are in different cache sets. * Returns 0 if successful, else a negative error code. */ int kvserver_put(kvserver_t *server, char *key, char *value) { // OUR CODE HERE int success; pthread_rwlock_t *lock = kvcache_getlock(&server->cache, key); if (lock == NULL) return ERRKEYLEN; pthread_rwlock_wrlock(lock); if ((success = kvcache_put(&server->cache, key, value)) < 0) { pthread_rwlock_unlock(lock); return success; } pthread_rwlock_unlock(lock); return kvstore_put(&server->store, key, value); }
int tpcmaster_get_cached(void) { int ret; pthread_rwlock_t *cachelock = kvcache_getlock(&testmaster.cache, "KEY"); pthread_rwlock_wrlock(cachelock); ret = kvcache_put(&testmaster.cache, "KEY", "VAL"); pthread_rwlock_unlock(cachelock); ASSERT_EQUAL(ret, 0); reqmsg.key = "KEY"; tpcmaster_handle_get(&testmaster, &reqmsg, &respmsg); ASSERT_EQUAL(respmsg.type, GETRESP); ASSERT_STRING_EQUAL(respmsg.key, "KEY"); ASSERT_STRING_EQUAL(respmsg.value, "VAL"); return 1; }
/* Attempts to get KEY from SERVER. Returns 0 if successful, else a negative * error code. If successful, VALUE will point to a string which should later * be free()d. If the KEY is in cache, take the value from there. Otherwise, * go to the store and update the value in the cache. */ int kvserver_get(kvserver_t *server, char *key, char **value) { // OUR CODE HERE int ret; pthread_rwlock_t *lock = kvcache_getlock(&server->cache, key); if (lock == NULL) return ERRKEYLEN; pthread_rwlock_rdlock(lock); if (kvcache_get(&server->cache, key, value) == 0) { pthread_rwlock_unlock(lock); return 0; } pthread_rwlock_unlock(lock); if ((ret = kvstore_get(&server->store, key, value)) < 0) return ret; pthread_rwlock_wrlock(lock); ret = kvcache_put(&server->cache, key, *value); // what happens if this is unsuccessful? pthread_rwlock_unlock(lock); return ret; }