Hatena::ブログ(Diary)

qtakamitsuの日記

2011-09-04

移転。

はてダでもなく、tDiary でもなく、tmblr へ http://qtakamitsu.tumblr.com/

tDiaryhttp://qtkmz.jp/d/

2011-07-20

RubyKaigi 2011 に行ってきました

1日目と2日目は現地で、3日目は ust での視聴でした。

感じたことをつらつらと。メモと感想が混ざっているので、あとで直す。

  • 1日目
    • 面白そうな話。だけど、英語。
    • 英語を聞き取れるようになりたい。それと、しゃべりも
    • Ruby でもきちんと基礎を押さえてれば、大規模なWebシステムでもいける
    • リアルタイムプロファイラが面白そう。だけれど、冒頭を聞き逃した。
    • あとで、ust 録画を見直す
    • "たこ焼き仮面" って何?
    • リスク回避の回避は難しい
    • 質問でもあったけれど、モチベーションを保っていられたのは感服
    • こういう状況は目に浮かぶ
  • 2日目
    • ThreadGroup。わかったような、わからなかったような
    • 名前は見聞きしていたけれど、初めて角谷さんを見ました。
    • 楽しい人なんだなーと
    • 楽しんでいる人たちのいるとこの一員になる
    • 3つのチャレンジは日本には早いと言っていたけれど、こういうことがくることを準備しておかないといけないんだろうな
    • Inspire Someone
    • Diversify
    • Get Out of the Rut
    • 8人はWindows環境のための修正
    • Yet Another Ruby OS -> YARuOS
    • 言語の壁は課題
    • Razor というテンプレートエンジンは、良さそう

  • 3日目
    • Regional RubyKaigi に興味があって
    • 地域 Ruby を始めるなら、 Regional RubyKaigiメーリングリストに必要な情報を post する
    • 「参加希望を出すのは怖い。」でも、がぶりつけ!
    • Good Looser。失敗したこと別の機会にネタにする
    • 地域でも、既に地域 Ruby みたいな活動はあるかもしれない
    • 地域Ruby 間で、人の行き来があって、いい
    • 話し合っていると、話が膨らむことがある
    • Regional RubyKaigi の条件は、Rubyist の集まりで何かをする。抽象的
    • るびまにレポートを出すのが条件といえば条件。他の人に伝える。多くの人に知らせるという意味で。
    • 2日目の「Inspire Someone」に繋がっているのかな
    • 多様とバラバラの違い
    • 何かに気づく場
    • 人が変わってアクションを起こす

2011-06-13

C で HBase にアクセスする

こちらが本題で、JNI を使って C から HBase にアクセスしてみる、というもの。これまでの JNI の動作確認のまとめみたいなものです。

C だと、thriftHTTP(REST) を使って HBase にアクセスする方法はあるけれど。

自作した JavaMyHTable クラスを C から呼び出し、HBase にアクセスするというもの。

まだまだ改良の余地がありそうだったり、エラー処理が足りなかったりするが、JNI を調べる過程で直していこうかな。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "jni.h"

#ifdef DEBUG
#  define  TRACE(s, f, ...) fprintf(s, f, __VA_ARGS__)
#else
#  define  TRACE(s, f, ...)
#endif


typedef struct {
    // public MyHTable();
    //   Signature: ()V
    jmethodID  init;

    // public void setTableName(java.lang.String);
    //   Signature: (Ljava/lang/String;)V
    jmethodID  setTableName;

    // public java.lang.String getTableName();
    //   Signature: ()Ljava/lang/String;
    jmethodID  getTableName;

    // public void configure();
    //   Signature: ()V
//    jmethodID  method_configure;

    // public void configure(java.lang.String, java.lang.String);
    //   Signature: (Ljava/lang/String;Ljava/lang/String;)V
    jmethodID  configure_param_with_conf_log;

    // public void configure(java.lang.String);
    //   Signature: (Ljava/lang/String;)V
//    jmethodID  method_configure_param_with_conf;

//    jmethodID  method_configure_param_with_log;

    // public void connect();
    //   Signature: ()V
    jmethodID  connect;

    // public void close();
    //   Signature: ()V
    jmethodID  close;

    // public java.lang.String[] get(java.lang.String, java.lang.String[])   throws java.io.IOException;
    //   Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
    jmethodID  get;
} MyHTableClassMethod;

typedef struct _MyHTableClass MyHTableClass;
struct _MyHTableClass {
    jobject obj;

    int(*set_table_name)(MyHTableClass *class, JNIEnv *jenv, char *table_name);
    char *(*get_table_name)(MyHTableClass *class, JNIEnv *jenv);
    int(*configure)(MyHTableClass *class, JNIEnv *jenv, char *conf, char *log);
    int(*connect)(MyHTableClass *class, JNIEnv *jenv);
    int(*close)(MyHTableClass *class, JNIEnv *jenv);
    char **(*get)(MyHTableClass *class, JNIEnv *jenv, char *row, char *columns[]);
};

static jclass g_MyHTableClass = 0;
static MyHTableClassMethod g_MyHTableClassMethod = { 0 };


int example_MyHTable(JavaVM *jvm, JNIEnv *jenv);

int MyHTableClass_init(JNIEnv *jenv);
MyHTableClass *MyHTableClass_alloc(JNIEnv *jenv);
int MyHTable_set_table_name(MyHTableClass *class, JNIEnv *jenv, char *table_name);
char *MyHTable_get_table_name(MyHTableClass *class, JNIEnv *jenv);
int MyHTable_configure(MyHTableClass *class, JNIEnv *jenv, char *conf, char *log);
int MyHTable_connect(MyHTableClass *class, JNIEnv *jenv);
int MyHTable_close(MyHTableClass *class, JNIEnv *jenv);
char **MyHTable_get(MyHTableClass *class, JNIEnv *jenv, char *row, char *columns[]);

jobjectArray CharsArray2JStringArray(JNIEnv *jenv, char **chars_array);
char **JStringArray2CharsArray(JNIEnv *jenv, jobjectArray jarray);


int main(int argc, char **argv)
{
    int            ret;
    JNIEnv         *jenv;
    JavaVM         *jvm;
    JavaVMInitArgs jvm_args;
    int            i;
    int            jvm_options_length;
    JavaVMOption   *jvm_options;

    jvm_options = NULL;
    jvm_options_length = 0;

    if (1 < argc) {
        jvm_options_length = argc - 1;

        jvm_options = (JavaVMOption *)malloc(sizeof(JavaVMOption) * jvm_options_length);
        if (jvm_options == NULL) {
            TRACE(stderr, "out of memory\n");
            exit(255);
        }

        for (i = 1; i < argc; i++) {
            jvm_options[i - 1].optionString = argv[i];
            TRACE(stderr, "options[%d] = [%s]\n", i, jvm_options[i - 1].optionString);
        }
    }

    jvm_args.version            = JNI_VERSION_1_6;
    jvm_args.options            = jvm_options;
    jvm_args.nOptions           = jvm_options_length;
    jvm_args.ignoreUnrecognized = 1;

    ret = JNI_CreateJavaVM(&jvm, (void**)&jenv, &jvm_args);
    if (ret < 0) {
        TRACE(stderr, "cannot create JVM\n");
        exit(1);
    }

    example_MyHTable(jvm, jenv);

    exit(0);
}

int example_MyHTable(JavaVM *jvm, JNIEnv *jenv)
{
    int ret;
    int i;
    char *table_name;
    MyHTableClass *table;
    char *columns[] = { "log1:date", "log1:host", "log1:path", "log1:user", NULL };
    char **values;

    ret = MyHTableClass_init(jenv);
    if (ret != 0) {
        TRACE(stderr, "<%s:%d> MyHTableClass_init() failed\n", __FILE__, __LINE__);
        return -1;
    }

    table = MyHTableClass_alloc(jenv);
    if (table == NULL) {
        TRACE(stderr, "<%s:%d> MyHTableClass_alloc() failed\n", __FILE__, __LINE__);
        return -1;
    }

    table->set_table_name(table, jenv, "app1");

    table_name = table->get_table_name(table, jenv);
    if (table_name != NULL) {
        TRACE(stderr, "<%s:%d> table_name = %s\n", __FILE__, __LINE__, table_name);
    }

    table->configure(table, jenv, "./hbase-site.xml", "./hbase.log4j.properties");

    table->connect(table, jenv);

    values = table->get(table, jenv, "row1", columns);

    for (i = 0; values[i] != NULL; i++) {
        printf("%s = %s\n", columns[i], values[i]);
    }

    table->close(table, jenv);

    TRACE(stderr, "<%s:%d> example_MyHTable() succeeded\n", __FILE__, __LINE__);

    return 0;
}

int MyHTableClass_init(JNIEnv *jenv)
{
    MyHTableClass *this;

    if (g_MyHTableClass == 0) {
        g_MyHTableClass = (*jenv)->FindClass(jenv, "MyHTable");
        if (g_MyHTableClass == 0) {
            // TODO: Check to see if you need error handling
            return -1;
        }
    }

    // public MyHTable();
    //   Signature: ()V
    g_MyHTableClassMethod.init = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "<init>", "()V");
    if (g_MyHTableClassMethod.init == 0) {
        return -1;
    }

    // public void setTableName(java.lang.String);
    //   Signature: (Ljava/lang/String;)V
    g_MyHTableClassMethod.setTableName = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "setTableName", "(Ljava/lang/String;)V");
    if (g_MyHTableClassMethod.setTableName == 0) {
        return -1;
    }

    // public java.lang.String getTableName();
    //   Signature: ()Ljava/lang/String;
    g_MyHTableClassMethod.getTableName = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "getTableName", "()Ljava/lang/String;");
    if (g_MyHTableClassMethod.getTableName == 0) {
        return -1;
    }

    // public void configure(java.lang.String, java.lang.String);
    //   Signature: (Ljava/lang/String;Ljava/lang/String;)V
    g_MyHTableClassMethod.configure_param_with_conf_log = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "configure", "(Ljava/lang/String;Ljava/lang/String;)V");
    if (g_MyHTableClassMethod.configure_param_with_conf_log == 0) {
        return -1;
    }

    // public void connect();
    //   Signature: ()V
    g_MyHTableClassMethod.connect = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "connect", "()V");
    if (g_MyHTableClassMethod.connect == 0) {
        return -1;
    }

    // public void close();
    //   Signature: ()V
    g_MyHTableClassMethod.close = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "close", "()V");
    if (g_MyHTableClassMethod.close == 0) {
        return -1;
    }

    // public java.lang.String[] get(java.lang.String, java.lang.String[])   throws java.io.IOException;
    //   Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
    g_MyHTableClassMethod.get = (*jenv)->GetMethodID(jenv, g_MyHTableClass, "get", "(Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;");
    if (g_MyHTableClassMethod.get == 0) {
        return -1;
    }

    return 0;
}

MyHTableClass *MyHTableClass_alloc(JNIEnv *jenv)
{
    MyHTableClass *class;
    jobject obj;

    class = (MyHTableClass*)malloc(sizeof(MyHTableClass));
    if (class == NULL) {
        return NULL;
    }

    obj = (*jenv)->NewObject(jenv, g_MyHTableClass, g_MyHTableClassMethod.init);
    if (obj == 0) {
        return NULL;
    }

    class->obj = obj;

    class->set_table_name = MyHTable_set_table_name;
    class->get_table_name = MyHTable_get_table_name;
    class->configure = MyHTable_configure;
    class->connect = MyHTable_connect;
    class->close = MyHTable_close;
    class->get = MyHTable_get;

    return class;
}

int MyHTable_set_table_name(MyHTableClass *class, JNIEnv *jenv, char *table_name)
{
    jstring js_table_name;

    js_table_name = (*jenv)->NewStringUTF(jenv, table_name);
    if (js_table_name == NULL) {
        return -1;
    }

    (*jenv)->CallVoidMethod(jenv, class->obj, g_MyHTableClassMethod.setTableName, js_table_name);

    (*jenv)->DeleteLocalRef(jenv, js_table_name);

    return 0;
}

char *MyHTable_get_table_name(MyHTableClass *class, JNIEnv *jenv)
{
    jstring ret_val;
    const char *val;
    char *table_name;

    ret_val = (*jenv)->CallObjectMethod(jenv, class->obj, g_MyHTableClassMethod.getTableName, NULL);

    val = (*jenv)->GetStringUTFChars(jenv, ret_val, 0);

    table_name = strdup(val);

    (*jenv)->ReleaseStringUTFChars(jenv, ret_val, val);

    return table_name;
}

int MyHTable_configure(MyHTableClass *class, JNIEnv *jenv, char *conf, char *log)
{
    jstring js_conf;
    jstring js_log;
 
    js_conf = (*jenv)->NewStringUTF(jenv, conf);
    if (js_conf == NULL) {
        return -1;
    }

    js_log = (*jenv)->NewStringUTF(jenv, log);
    if (js_log == NULL) {
        (*jenv)->DeleteLocalRef(jenv, js_conf);
        return -1;
    }

    (*jenv)->CallVoidMethod(jenv, class->obj, g_MyHTableClassMethod.configure_param_with_conf_log, js_conf, js_log);

    if ((*jenv)->ExceptionOccurred(jenv)) {
        (*jenv)->ExceptionDescribe(jenv);
        (*jenv)->ExceptionClear(jenv);
        (*jenv)->DeleteLocalRef(jenv, js_conf);
        (*jenv)->DeleteLocalRef(jenv, js_log);
        return -1;
    }

    (*jenv)->DeleteLocalRef(jenv, js_conf);
    (*jenv)->DeleteLocalRef(jenv, js_log);

    return 0;
}

int MyHTable_connect(MyHTableClass *class, JNIEnv *jenv)
{
    (*jenv)->CallVoidMethod(jenv, class->obj, g_MyHTableClassMethod.connect);

    if ((*jenv)->ExceptionOccurred(jenv)) {
        (*jenv)->ExceptionDescribe(jenv);
        (*jenv)->ExceptionClear(jenv);
        return -1;
    }

    return 0;
}

int MyHTable_close(MyHTableClass *class, JNIEnv *jenv)
{
    (*jenv)->CallVoidMethod(jenv, class->obj, g_MyHTableClassMethod.close);

    if ((*jenv)->ExceptionOccurred(jenv)) {
        (*jenv)->ExceptionDescribe(jenv);
        (*jenv)->ExceptionClear(jenv);
        return -1;
    }

    return 0;
}

char **MyHTable_get(MyHTableClass *class, JNIEnv *jenv, char *row, char *columns[])
{
    jstring js_row;
    jobjectArray jarray_columns;
    jarray jarray_ret;
    char **values;

    js_row = (*jenv)->NewStringUTF(jenv, row);
    if (js_row == NULL) {
        TRACE(stderr, "<%s:%d> NewStringUTF() failed\n", __FILE__, __LINE__);
        return NULL;
    }

    jarray_columns = CharsArray2JStringArray(jenv, columns);
    if (jarray_columns == NULL) {
        TRACE(stderr, "<%s:%d> CharsArray2JStringArray() failed\n", __FILE__, __LINE__);
        return NULL;
    }

    jarray_ret = (*jenv)->CallObjectMethod(jenv, class->obj, g_MyHTableClassMethod.get, js_row, jarray_columns);

    if ((*jenv)->ExceptionOccurred(jenv)) {
        (*jenv)->ExceptionDescribe(jenv);
        (*jenv)->ExceptionClear(jenv);
        return NULL;
    }

    if (jarray_ret == NULL) {
        TRACE(stderr, "<%s:%d> CallObjectMethod() failed\n", __FILE__, __LINE__);
        return NULL;
    }

    values = JStringArray2CharsArray(jenv, jarray_ret);
    if (values == NULL) {
        return NULL;
    }

    (*jenv)->DeleteLocalRef(jenv, js_row);
    (*jenv)->DeleteLocalRef(jenv, jarray_columns);

    return values;
}

jobjectArray CharsArray2JStringArray(JNIEnv *jenv, char **chars_array)
{
    int size;
    int i;
    jstring js;
    jobjectArray jstring_array;
    jclass string_array_class;

    string_array_class = (*jenv)->FindClass(jenv, "Ljava/lang/String;");
    if (string_array_class == NULL) {
        TRACE(stderr, "<%s:%d> FindClass() failed\n", __FILE__, __LINE__);
        return NULL;
    }

    for (i = 0; chars_array[i] != NULL; i++) {
        ;
    }
    size = i;

    TRACE(stderr, "<%s:%d> size = %d\n", __FILE__, __LINE__, size);

    jstring_array = (*jenv)->NewObjectArray(jenv, size, string_array_class, NULL);
    if (jstring_array == NULL) {
        TRACE(stderr, "<%s:%d> NewObjectArray() failed\n", __FILE__, __LINE__);
        return NULL;
    }

    for (i = 0; i < size; i++) {
        js = (*jenv)->NewStringUTF(jenv, chars_array[i]);

        (*jenv)->SetObjectArrayElement(jenv, jstring_array, i, js);

        (*jenv)->DeleteLocalRef(jenv, js);
    }

    return jstring_array;
}

char **JStringArray2CharsArray(JNIEnv *jenv, jobjectArray jarray)
{
    char **chars_array;
    int len;
    int i;
    const char *ret_val;
    jstring jst_ret;

    len = (*jenv)->GetArrayLength(jenv, jarray);

    chars_array = (char **)malloc(sizeof(char*) * (len + 1));
    if (chars_array == NULL) {
        TRACE(stderr, "<%s:%d> malloc() failed\n", __FILE__, __LINE__);
        return NULL;
    }

    for (i = 0; i < len; i++) {
        ret_val = "";

        jst_ret = (*jenv)->GetObjectArrayElement(jenv, jarray, i);
        if (jst_ret != NULL) {
            ret_val = (*jenv)->GetStringUTFChars(jenv, jst_ret, 0);
        }

        TRACE(stderr, "<%s:%d> %d) => %s\n", __FILE__, __LINE__, i, ret_val);

        chars_array[i] = strdup(ret_val);
        if (chars_array[i] == NULL) {
            // TODO: Add error handling
            return NULL;
        }

        if (jst_ret != NULL) {
            (*jenv)->ReleaseStringUTFChars(jenv, jst_ret, ret_val);
        }
    }
    chars_array[i] = NULL;

    return chars_array;
}

Java で HBase にアクセスする

Java で HBase 上のデータを取得してみる。

設定ファイルを指定してから、データを取得しているだけ。

久しぶりに Java で書いた気がする。でも、こんな程度だと書いたことに入らないかな。

HBase Javaメモ(Hishidama’s HBase Java Memo) を参考にしました。

import java.io.IOException;

import org.apache.log4j.PropertyConfigurator;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTableFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

public class MyHTable {

    private String tableName;

    Configuration conf;
    HTableFactory factory;
    HTableInterface table;

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableName() {
        return this.tableName;
    }

    public void configure() {
        this.conf = HBaseConfiguration.create();
    }

    public void configure(String hbaseConf, String log) {
        PropertyConfigurator.configure(log);

        this.conf = HBaseConfiguration.create();
        this.conf.addResource(new Path(hbaseConf));
    }

    public void configure(String hbaseConf) {
        this.conf = HBaseConfiguration.create();
        this.conf.addResource(new Path(hbaseConf));
    }

    public void configure(String log) {
        PropertyConfigurator.configure(log);
    }

    public void connect() {
        this.factory = new HTableFactory();
        this.table = factory.createHTableInterface(this.conf, Bytes.toBytes(this.tableName));
    }

    public void close() {
        factory.releaseHTableInterface(this.table);
    }

    public String[] get(String row, String[] columns) throws IOException {

        String[] values = new String[columns.length];

        Get g = new Get(Bytes.toBytes(row));

        Result r = this.table.get(g);

        for (int i = 0; i < columns.length; i++) {
            String[] params = columns[i].split(":", 2);

            byte[] val_byte = r.getValue(Bytes.toBytes(params[0]), Bytes.toBytes(params[1]));

            values[i] = Bytes.toString(val_byte);
        }

        return values;
    }


    public static void main(String[] args) throws IOException {
        MyHTable table = new MyHTable();

        table.setTableName("app1");

        table.configure("./hbase-site.xml", "./hbase.log4j.properties");
        table.connect();

        String[] columns = {
          "log1:date", "log1:host", "log1:path", "log1:user",
        };

        String[] values = table.get("row1", columns);

        System.out.println("row1 ----");
        for (int i = 0; i < values.length; i++) {
            System.out.println("  [" + columns[i] + "] = " + values[i]);
        }

        table.close();
    }
}

2011-05-08

ブログ移転?

せっかくドメインを取得したので、tDiary を立ててやってみようかと思います。

2011-04-17

Chiba.rb 鴨川

今週末に Chiba.rb で活動があります。

現在、まだ余裕があります。

懇親会も、泊まりもあり、楽しそうな会になりそうです。

これから、こういう勉強会みたいなのに参加していきたいな

http://kokucheese.com/event/index/9464/