size_t shardcache_client_offset(shardcache_client_t *c, void *key, size_t klen, uint32_t offset, void *data, uint32_t dlen) { int fd = -1; char *addr = select_node(c, key, klen, &fd); if (fd < 0) { c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK; snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr); return 0; } fbuf_t value = FBUF_STATIC_INITIALIZER; int rc = offset_from_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, key, klen, offset, dlen, &value, fd); if (rc == 0) { uint32_t to_copy = dlen > fbuf_used(&value) ? fbuf_used(&value) : dlen; if (data) memcpy(data, fbuf_data(&value), to_copy); c->errno = SHARDCACHE_CLIENT_OK; c->errstr[0] = 0; connections_pool_add(c->connections, addr, fd); fbuf_destroy(&value); return to_copy; } else { close(fd); c->errno = SHARDCACHE_CLIENT_ERROR_NODE; snprintf(c->errstr, sizeof(c->errstr), "Can't fetch data from node '%s'", addr); } fbuf_destroy(&value); return 0; }
size_t shardcache_client_get(shardcache_client_t *c, void *key, size_t klen, void **data) { int fd = -1; char *addr = select_node(c, key, klen, &fd); if (fd < 0) { c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK; snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr); return 0; } fbuf_t value = FBUF_STATIC_INITIALIZER; int rc = fetch_from_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, key, klen, &value, fd); if (rc == 0) { size_t size = fbuf_used(&value); if (data) *data = fbuf_data(&value); else fbuf_destroy(&value); c->errno = SHARDCACHE_CLIENT_OK; c->errstr[0] = 0; connections_pool_add(c->connections, addr, fd); return size; } else { close(fd); c->errno = SHARDCACHE_CLIENT_ERROR_NODE; snprintf(c->errstr, sizeof(c->errstr), "Can't fetch data from node '%s'", addr); return 0; } return 0; }
int shardcache_client_migration_begin(shardcache_client_t *c, shardcache_node_t **nodes, int num_nodes) { fbuf_t mgb_message = FBUF_STATIC_INITIALIZER; int i; for (i = 0; i < num_nodes; i++) { if (i > 0) fbuf_add(&mgb_message, ","); fbuf_printf(&mgb_message, "%s:%s", shardcache_node_get_string(nodes[i])); } for (i = 0; i < c->num_shards; i++) { char *addr = shardcache_node_get_address(c->shards[i]); int fd = connections_pool_get(c->connections, addr); if (fd < 0) { c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK; snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr); fbuf_destroy(&mgb_message); return -1; } int rc = migrate_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, fbuf_data(&mgb_message), fbuf_used(&mgb_message), fd); if (rc != 0) { close(fd); c->errno = SHARDCACHE_CLIENT_ERROR_NODE; snprintf(c->errstr, sizeof(c->errstr), "Node '%s' (%s) didn't aknowledge the migration\n", shardcache_node_get_label(c->shards[i]), addr); fbuf_destroy(&mgb_message); // XXX - should we abort migration on peers that have been notified (if any)? return -1; } connections_pool_add(c->connections, addr, fd); } fbuf_destroy(&mgb_message); c->errno = SHARDCACHE_CLIENT_OK; c->errstr[0] = 0; return 0; }
void fbuf_move(fbuf_t *fbufsrc, fbuf_t *fbufdst) { DEBUG_FBUF_INFO(fbufsrc, "source"); DEBUG_FBUF_INFO(fbufsrc, "destination"); fbuf_destroy(fbufdst); bcopy(fbufsrc, fbufdst, sizeof(fbuf_t)); fbufsrc->data = NULL; fbufsrc->used = fbufsrc->len = fbufsrc->skip = 0; fbufsrc->id = __sync_fetch_and_add(&fbuf_count, 1); }