読者です 読者をやめる 読者になる 読者になる

Boost::serialization & Tokyo Cabinet

プログラミング


Boost::serializationはC++のオブジェクトをシリアライズしてくれるライブラリ。例えば、↓みたいに書くだけでPersonクラスのオブジェクトをシリアライズしてくれる。(ただし、stringやvectorなどをシリアライズするには特別なヘッダファイルが必要)

class Person
{
public :
  int id;
  string name;
private :
  friend class boost::serialization::access;
  template<class Archive>
  void serialize (Archive& ar, unsigned int ver)
  {
    ar & id;
    ar & name;
  }
};

なるほど、friendクラスはこのためにあったのか(絶対違う)!しかし、シリアライズしたデータを単にファイルに書き出しても実のところあんまりうれしくない。どうせならDBにでも登録してあとで簡単に取り出せるようにしたい。


というわけでシリアライズしたオブジェクトをTokyo Cabinetに登録、取得するコードを書いてみた。とりあえずできるかどうか試してみたかっただけなので、割と適当だし、CとC++な書き方が混在してるけど、気にしない。

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>
#include <tcutil.h>
#include <tchdb.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <iostream>
#include <sstream>
#include <string>

using namespace std;

// ここにさっきのPersonクラス

#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

int main(int argc, char *argv[]){

  Person p1;
  p1.id = 1;
  p1.name = "cubicdaiya";
  ostringstream os;
  boost::archive::text_oarchive oa(os);
  oa << (const Person&) p1;
  string val(os.str());

  TCHDB *hdb;
  int ecode;
  char *value;
  hdb = tchdbnew();
  if(!tchdbopen(hdb, "casket.hdb", HDBOWRITER | HDBOCREAT)){
    ecode = tchdbecode(hdb);
    fprintf(stderr, "open error: %s\n", tchdberrmsg(ecode));
  }

  if(!tchdbput2(hdb, "data", val.c_str())){
    ecode = tchdbecode(hdb);
    fprintf(stderr, "put error: %s\n", tchdberrmsg(ecode));
  }

  value = tchdbget2(hdb, "data");
  if(!value){
    ecode = tchdbecode(hdb);
    fprintf(stderr, "get error: %s\n", tchdberrmsg(ecode));
  }

  Person p2;
  string ostr(value);
  free(value);
  istringstream is(ostr);
  boost::archive::text_iarchive ia(is);
  ia >> p2;
  cout << "id  :" << p2.id << endl;
  cout << "name:" << p2.name << endl;

  if(!tchdbclose(hdb)){
    ecode = tchdbecode(hdb);
    fprintf(stderr, "close error: %s\n", tchdberrmsg(ecode));
  }

  tchdbdel(hdb);

  return 0;
}

実行結果

narazuya@bokkko% g++ serialize_tc.cpp -ltokyocabinet -lz -lpthread -lm -lc -lboost_serialization-mt
narazuya@bokkko% ./a.out
id  :1
name:cubicdaiya
narazuya@bokkko%