Commit e6efb87f authored by Rob Latham's avatar Rob Latham
Browse files

simple put/get works

defined a library implementing kv_open, kv_close, kv_put, and kv_get.
Server wraps BwTree class locally.
parent fb96ddac
......@@ -8,7 +8,11 @@ lib_LTLIBRARIES = libkvclient.la \
libkvclient_la_SOURCES = src/kv-client.c
libkvserver_la_SOURCES = src/kv-server.cc
libkvserver_la_SOURCES = src/kv-server.cc \
src/BwTree/src/bwtree.cpp
libkvserver_la_CXXFLAGS = -pthread -std=c++11 -g -Wall -mcx16 -Wno-invalid-offsetof
libkvserver_la_CPPFLAGS = -I${srcdir}/src/BwTree/src
include_HEADERS = src/sds-keyval.h
......
= mochi service for keyvals
# mochi service for keyvals
- implement any old keyval in the backend
- project key-val interface out to clients
- server does the store/retrieve
= Build requirements
## Build requirements
- the ''mercury suite'': `mercury`, `margo`, `argobots`, `abt-snoozer`, and friends.
- autotools
- the [https://github.com/wangziqi2013/BwTree BwTree] implementation
## Issues
BwTree @ 35e678e9
Subproject commit 35e678e990e856398a1efed8d1d002a1b3f0be6a
......@@ -4,10 +4,10 @@
#include <abt-snoozer.h>
#include <abt.h>
#include <assert.h>
/* probably ends up in a standalone test program */
kv_context *kv_client_register(int argc, char **argv) {
int ret;
kv_context * context;
......@@ -34,6 +34,86 @@ kv_context *kv_client_register(int argc, char **argv) {
return context;
}
int kv_open(kv_context *context, char *name,
kv_type keytype, kv_type valtype) {
int ret = HG_SUCCESS;
hg_handle_t handle;
open_in_t open_in;
open_out_t open_out;
ret = HG_Create(context->hg_context, context->svr_addr,
context->open_id, &handle);
assert(ret == HG_SUCCESS);
open_in.name = name;
ret = margo_forward(context->mid, handle, &open_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &open_out);
assert(ret == HG_SUCCESS);
ret = open_out.ret;
HG_Free_output(handle, &open_out);
HG_Destroy(handle);
return ret;
}
/* we gave types in the open call. Will need to maintain in 'context' the
* size. */
int kv_put(kv_context *context, void *key, void *value) {
int ret;
hg_handle_t handle;
put_in_t put_in;
put_out_t put_out;
ret = HG_Create(context->hg_context, context->svr_addr,
context->put_id, &handle);
assert(ret == HG_SUCCESS);
put_in.key = *(int*)key;
put_in.value = *(int*)value;
ret = margo_forward(context->mid, handle, &put_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &put_out);
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &put_out);
HG_Destroy(handle);
}
int kv_get(kv_context *context, void *key, void *value)
{
int ret;
hg_handle_t handle;
get_in_t get_in;
get_out_t get_out;
ret = HG_Create(context->hg_context, context->svr_addr,
context->get_id, &handle);
get_in.key = *(int*)key;
ret = margo_forward(context->mid, handle, &get_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &get_out);
*(int*) value = get_out.value;
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &get_out);
HG_Destroy(handle);
}
int kv_close(kv_context *context)
{
int ret;
hg_handle_t handle;
put_in_t close_in;
put_out_t close_out;
ret = HG_Create(context->hg_context, context->svr_addr,
context->close_id, &handle);
assert(ret == HG_SUCCESS);
ret = margo_forward(context->mid, handle, &close_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &close_out);
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &close_out);
HG_Destroy(handle);
}
int kv_client_deregister(kv_context *context) {
HG_Addr_free(context->hg_class, context->svr_addr);
......
......@@ -8,6 +8,15 @@
#include <abt.h>
#include <assert.h>
/* keyval-specific stuff can go here */
#include <bwtree.h>
#include <vector>
wangziqi2013::bwtree::BwTree<int, int> TREE;
static hg_return_t open_handler(hg_handle_t);
DECLARE_MARGO_RPC_HANDLER(open_handler);
static hg_return_t open_handler(hg_handle_t h)
{
hg_return_t ret;
......@@ -16,9 +25,20 @@ static hg_return_t open_handler(hg_handle_t h)
const struct hg_info* info = HG_Get_info(h);
margo_instance_id mid;
printf("SERVER: OPEN\n");
ret = HG_Get_input(h, &in);
printf("SERVER: OPEN %s\n", in.name);
TREE.SetDebugLogging(0);
TREE.UpdateThreadLocal(1);
TREE.AssignGCID(0);
/* TODO: something with in.keytype and in.valtype. In C I would get
* away with sloppy casting. Not sure how to do the same with a C++
* template. */
/* I don't know how to check for error */
out.ret = HG_SUCCESS;
// this works
ret = HG_Respond(h, NULL, NULL, &out);
// but this did not?
......@@ -31,7 +51,7 @@ static hg_return_t open_handler(hg_handle_t h)
return HG_SUCCESS;
}
DEFINE_MARGO_RPC_HANDLER(open_handler);
DEFINE_MARGO_RPC_HANDLER(open_handler)
static hg_return_t close_handler(hg_handle_t h)
{
......@@ -58,9 +78,10 @@ static hg_return_t put_handler(hg_handle_t h)
put_in_t in;
put_out_t out;
printf("SERVER: PUT\n");
ret = HG_Get_input(h, &in);
printf("SERVER: PUT key = %d val = %d\n", in.key, in.value);
TREE.Insert(in.key, in.value);
assert(ret == HG_SUCCESS);
ret = HG_Respond(h, NULL, NULL, &out);
......@@ -77,11 +98,20 @@ static hg_return_t get_handler(hg_handle_t h)
get_in_t in;
get_out_t out;
printf("SERVER: GET\n");
ret = HG_Get_input(h, &in);
assert(ret == HG_SUCCESS);
/*void GetValue (const KeyType &search_key, std::vector< ValueType > &value_list) */
std::vector<int> value;
TREE.GetValue(in.key, value);
if (value.size() >= 1) {
printf("SERVER: GET: key=%d, value=%d\n",
in.key, value.front());
}
out.value = value.front();
ret = HG_Respond(h, NULL, NULL, &out);
assert(ret == HG_SUCCESS);
......
#include <mercury.h>
#include <mercury_macros.h>
#include <mercury_proc_string.h>
#include <margo.h>
#include <abt.h>
#include <abt-snoozer.h>
......@@ -13,6 +15,16 @@ sdskeyval_put();
sdskeyval_get();
#endif
typedef int kv_id;
typedef enum {
KV_INT,
KV_FLOAT,
KV_DOUBLE,
KV_STRING
} kv_type;
/* do we need one for server, one for client? */
typedef struct kv_context_s {
hg_class_t * hg_class;
......@@ -24,36 +36,41 @@ typedef struct kv_context_s {
hg_id_t get_id;
hg_id_t open_id;
hg_id_t close_id;
/* some keyval dodad goes here for the server I guess? */
/* some keyval dodad goes here so the server can discriminate. Seems
* like it should be some universal identifier we can share with other
* clients */
kv_id kv;
} kv_context;
/* struggling a bit with types. We'll need to create one of these for every
* type? */
MERCURY_GEN_PROC(put_in_t,
((int32_t)(x))\
((int32_t)(y)))
((int32_t)(key))\
((int32_t)(value)) )
MERCURY_GEN_PROC(put_out_t, ((int32_t)(ret)))
MERCURY_GEN_PROC(put_out_t, ((int32_t)(ret)) )
MERCURY_GEN_PROC(get_in_t,
((int32_t)(x))\
((int32_t)(y)))
((int32_t)(key)) )
MERCURY_GEN_PROC(get_out_t, ((int32_t)(ret)))
MERCURY_GEN_PROC(get_out_t,
((int32_t)(value)) ((int32_t)(ret)) )
MERCURY_GEN_PROC(open_in_t,
((int32_t)(x))\
((int32_t)(y)))
((hg_string_t)(name))\
((int32_t) (keytype))\
((int32_t) (valtype)) )
MERCURY_GEN_PROC(open_out_t, ((int32_t)(ret)))
MERCURY_GEN_PROC(close_in_t,
((int32_t)(x))\
((int32_t)(y)))
MERCURY_GEN_PROC(close_out_t, ((int32_t)(ret)))
((int32_t)(y)) )
MERCURY_GEN_PROC(close_out_t, ((int32_t)(ret)) )
kv_context *kv_client_register(int argc, char **argv);
......@@ -63,6 +80,13 @@ kv_context * kv_server_register(int argc, char **argv);
int kv_client_deregister(kv_context *context);
int kv_server_deregister(kv_context *context);
/* client-side routines wrapping up all the RPC stuff */
int kv_open(kv_context *context, char *name,
kv_type keytype, kv_type valtype);
int kv_put(kv_context *context, void *key, void *value);
int kv_get(kv_context *context, void *key, void *value);
int kv_close(kv_context *context);
#if defined(__cplusplus)
}
......
......@@ -18,49 +18,20 @@ int main(int argc, char **argv) {
assert(ret == HG_SUCCESS);
/* open */
ret = HG_Create(context->hg_context, context->svr_addr,
context->open_id, &handle);
assert(ret == HG_SUCCESS);
ret = margo_forward(context->mid, handle, &open_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &open_out);
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &open_out);
HG_Destroy(handle);
ret = kv_open(context, "booger", KV_INT, KV_INT);
/* put */
ret = HG_Create(context->hg_context, context->svr_addr,
context->put_id, &handle);
assert(ret == HG_SUCCESS);
ret = margo_forward(context->mid, handle, &put_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &put_out);
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &put_out);
HG_Destroy(handle);
int key = 10;
int val = 10;
ret = kv_put(context, &key, &val);
/* get */
ret = HG_Create(context->hg_context, context->svr_addr,
context->get_id, &handle);
ret = margo_forward(context->mid, handle, &get_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &get_out);
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &get_out);
HG_Destroy(handle);
int remote_val;
ret = kv_get(context, &key, &remote_val);
printf("key: %d in: %d out: %d\n", key, val, remote_val);
/* close */
ret = HG_Create(context->hg_context, context->svr_addr,
context->close_id, &handle);
assert(ret == HG_SUCCESS);
ret = margo_forward(context->mid, handle, &close_in);
assert(ret == HG_SUCCESS);
ret = HG_Get_output(handle, &close_out);
assert(ret == HG_SUCCESS);
HG_Free_output(handle, &close_out);
HG_Destroy(handle);
ret = kv_close(context);
kv_client_deregister(context);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment