Example #1
0
/* 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);
}
Example #2
0
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;
}
Example #3
0
/* Removes the given KEY from 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_del(kvserver_t *server, char *key) {
  // OUR CODE HERE
  int ret;
  pthread_rwlock_t *lock = kvcache_getlock(&server->cache, key);
  if (lock == NULL) return ERRKEYLEN;
  pthread_rwlock_wrlock(lock);
  if ((ret = kvstore_del(&server->store, key)) < 0) {
    pthread_rwlock_unlock(lock);
    return ret;
  }
  pthread_rwlock_unlock(lock);
  kvcache_del(&server->cache, key); // if not in server's cache, that's okay
  return 0;
}
Example #4
0
/* 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;
}
Example #5
0
int kvserver_cache_concurrent_gets_rdlock(void) {
  pthread_rwlock_t *cachelock;
  pthread_t thread;

  reqmsg.type = PUTREQ;
  reqmsg.key = "MYKEY";
  reqmsg.value = "MYVALUE";
  kvserver_handle_no_tpc(&testserver, &reqmsg, &respmsg);
  ASSERT_EQUAL(respmsg.type, RESP);
  ASSERT_STRING_EQUAL(respmsg.message, MSG_SUCCESS);

  synch = 0;
  reqmsg.type = GETREQ;

  cachelock = kvcache_getlock(&testserver.cache, "MYKEY");
  pthread_rwlock_rdlock(cachelock);
  pthread_create(&thread, NULL, kvserver_concurrent_helper, NULL);
  usleep(1000 * SLEEP_TIME); /* Give the get request a chance to run. */
  ASSERT_EQUAL(synch, 1); /* Ensure the get request was able to complete already. */
  pthread_rwlock_unlock(cachelock);
  pthread_join(thread, NULL);
  return 1;
}
Example #6
0
int kvserver_cache_concurrent_get_cache_writes(void) {
  pthread_rwlock_t *cachelock;
  pthread_t thread;
  kvserver_init(&testserver, KVSERVER_DIRNAME, 1, 2, 1, KVSERVER_HOSTNAME, KVSERVER_PORT, false);
  reqmsg.type = PUTREQ;
  reqmsg.key = "MYKEY1";
  reqmsg.value = "MYVALUE1";
  kvserver_handle_no_tpc(&testserver, &reqmsg, &respmsg);
  ASSERT_EQUAL(respmsg.type, RESP);
  ASSERT_STRING_EQUAL(respmsg.message, MSG_SUCCESS);

/* Clear MYKEY1 from the cache */
  reqmsg.key = "MYKEY2";
  reqmsg.value = "MYVALUE2";
  kvserver_handle_no_tpc(&testserver, &reqmsg, &respmsg); 
  ASSERT_EQUAL(respmsg.type, RESP);
  ASSERT_STRING_EQUAL(respmsg.message, MSG_SUCCESS);
  reqmsg.key = "MYKEY3";
  reqmsg.value = "MYVALUE3";
  kvserver_handle_no_tpc(&testserver, &reqmsg, &respmsg); 
  ASSERT_EQUAL(respmsg.type, RESP);
  ASSERT_STRING_EQUAL(respmsg.message, MSG_SUCCESS);

  synch = 0;
  reqmsg.type = GETREQ;
  reqmsg.key = "MYKEY1";

  cachelock = kvcache_getlock(&testserver.cache, "MYKEY1");
  pthread_rwlock_rdlock(cachelock);
  pthread_create(&thread, NULL, kvserver_concurrent_helper, NULL);
  usleep(1000 * SLEEP_TIME); /* Give the get request a chance to run. */
  ASSERT_EQUAL(synch, 0); /* Ensure the get request didn't complete yet. */
  pthread_rwlock_unlock(cachelock);
  pthread_join(thread, NULL);
  ASSERT_EQUAL(synch, 1); /* Ensure that the get request was able to run after the lock was released. */
  return 1;
}