/*
 * Client interface to RPC stubs for blockdbd.
 */

#ifndef blockdbc_h
#define blockdbc_h 1

#include "amisc.h"
#include "async.h"
#include "arpc.h"
#include "block_proto.h"
#include "ihash.h"

// #define BLOCKCACHE

struct cacheent
{
  str key;
  str value;
  bool dirty;
  ihash_entry<cacheent> hlink;
};


class blockdbc {
public:
  blockdbc(struct sockaddr_in sin);
  void put(str key, str value, callback<void, bool>::ref cb);
  void get(str key, callback<void, bool, str>::ref cb);
  void remove(str key, callback<void, bool>::ref cb);
  void flush(str key, callback<void>::ref cb);
  void test();
  
private:
  int fd;
  ptr<axprt> x;
  ptr<aclnt> c;
  struct sockaddr_in server;
  ihash<const str, cacheent, &cacheent::key, &cacheent::hlink> cache;

  void real_put(str key, str value, callback<void, bool>::ref cb);
  void real_get(str key, callback<void, bool, str>::ref cb);
  void put_done(callback<void, bool>::ref cb,
                bool *res, clnt_stat err);
  void get_done(callback<void, bool, str>::ref cb, str key,
                get_result *r, clnt_stat err);
  void get_xcb(callback<void, bool, str>::ref cb, str v);
  void remove_done(callback<void, bool>::ref cb,
                   bool *res, clnt_stat err);
  void test_cb1(bool ok);
  void test_cb2(str wanted, bool ok, str value);
  str hex(str s);
  void update_cache(str key, str val, bool dirty);
  void get_from_cache(str key, str value,
                      callback<void, bool, str>::ref cb);
  void flush_on_real_put(callback<void>::ref cb, bool ok);
};

#endif blockdbc_h
