日曜日, 9月 18, 2011

Cygwin+Hiveで必要になる修正(File.separatorも!)

Hive内部では、当然HDFSのPath操作を各種行っているのだけど、、そのセパレータ(HDFSなら"/"であるべき)を、File.separatorシステム変数から取得している。 Cygwinではこれが"¥"になってしまうので、修正として先にで紹介したものだけでなく、ql/io/HiveFileFormatUtils.javaのdoGetPartitionDescFromPath()も変更が必要だった。

  private static PartitionDesc doGetPartitionDescFromPath(

-snip-

    if (part == null) {
      String dirStr = dir.toString();
      //int dirPathIndex = dirPath.lastIndexOf(File.separator);
      //int dirStrIndex = dirStr.lastIndexOf(File.separator);
      int dirPathIndex = dirPath.lastIndexOf("/");
      int dirStrIndex = dirStr.lastIndexOf("/");
      while (dirPathIndex >= 0 && dirStrIndex >= 0) {
        dirStr = dirStr.substring(0, dirStrIndex);
        dirPath = dirPath.substring(0, dirPathIndex);
        //first try full match
        part = pathToPartitionInfo.get(dirStr);
        if (part == null) {
          // LOG.warn("exact match not found, try ripping input path's theme and authority");
          part = pathToPartitionInfo.get(dirPath);
        }
        if (part != null) {
          break;
        }
        //dirPathIndex = dirPath.lastIndexOf(File.separator);
        //dirStrIndex = dirStr.lastIndexOf(File.separator);
        dirPathIndex = dirPath.lastIndexOf("/");
        dirStrIndex = dirStr.lastIndexOf("/");
      }
    }
    return part;
  }
というか、File.separatorでgrepすると多数あるので、、、他にも危ないところはありそう。。。

月曜日, 6月 20, 2011

GW-SC150Nの動き

この無線→有線コンバータは、とても便利なんだけど、どうも説明書などが詳細まで書かれていないので判然としないので調べてみた。

①自分自身は上位の(無線LANの)クラスCの".249"となる
②この249は上位から払い出されたものではなく勝手に使う
③自分の有線LAN配下には自身がDHCPサーバとなりIPを払い出す(※)
④但し払い出すIPのクラスC部分は上位の(無線LANの)ものを使う
⑤故に有線と上位(=無線LAN)で同じ第四オクテットを払い出しうる

ということか。

上位で見ていても有線上のMACが見えて来ないので、(※)ではNATしている=全て自分(GW-SC150N)が通信していることにすることは確認できた気がする。

日曜日, 1月 09, 2011

Googleの検索機能をAPI的に使える!?

Googleドキュメントにuploadした文書は、"Google Documents List Data API"経由で全文検索ができるらしい。これをJavascriptからやってみました(Rhino)。

/*
 * FullTextSearch
 * http://bit.ly/i4QaUO
 */

importPackage(com.google.gdata.client.docs);
importPackage(com.google.gdata.client);
importPackage(com.google.gdata.data.docs);
importPackage(java.util);
importPackage(java.util.logging);

function getDocsService(applicationName, username, password){
    var service = new DocsService(applicationName)
    service.setUserCredentials(username, password)
    return service;
}

var username = 'xxxx@gmail.com';
var password = 'xxxx';
var client   = getDocsService('fts-test-1', username, password);

var feedUri  = new java.net.URL('https://docs.google.com/feeds/default/private/full/');
var query    = new DocumentQuery(feedUri);

var qStr     = "first"; // 検索文字列
query.setFullTextQuery(qStr);

var feed = client.getFeed(
    query,
    java.lang.Class.forName("com.google.gdata.data.docs.DocumentListFeed")
);

print( feed );

if(feed){
    var entries = feed.getEntries();

    for (var i = 0; i < entries.size();i++){
        print("- " + entries.get(i).getTitle().getPlainText());
    }

    print(entries.size());
}

もちろん元ネタは、ぶいてくさんの「すごいのはGDriveより全文検索でしょ!?」です。カスタム検索という機能は提供されていましたが、検索結果としてHTMLが返されたりと、プログラムから使える感じではなかったのですが、これは便利そうです。

日曜日, 1月 02, 2011

JavaからJavascriptを使うとき

以下では、組込み変数のenvironmentなどがない環境での実行になってしまう。

Context cx = Context.enter();
Scriptable scope = new ImporterTopLevel(cx);
Object obj = cx.evaluateReader(scope, reader, "JsScript", 1, null);

これは以下のように、GlobalオブジェクトでContectを初期化することで(それら変数が入った)シェルと同様の環境で実行させることができる。
Global global = new Global();
Context cx = ContextFactory.getGlobal().enterContext();
global.init(cx);
Scriptable scope = cx.initStandardObjects(global);
Object obj = cx.evaluateReader(scope, reader, "JsScript", 1, null);

EnvJSの過去MLで知りました。
なお、ここのGlobalはorg.mozilla.javascript.tools.shell.Globalです。

火曜日, 12月 21, 2010

mahoutでkmeans!

以下HADOOP_CLASSPATHを設定して、

$ export HADOOP_CLASSPATH=dependency/mahout-math-0.4.jar:dependency/mahout-core-0.4.jar:dependency/mahout-utils-0.4.jar:dependency/google-collections-1.0-rc2.jar:dependency/gson-1.3.jar:dependency/mahout-collections-1.0.jar:dependency/commons-cli-2.0-mahout.jar

以下を実行。なぜかKMeansはhadoopがローカルで待ち受けていないと動かない様子。

$ ~/hadoop-0.20.2/bin/hadoop jar mahout-examples-0.4.jar org.apache.mahout.clustering.display.DisplayKMeans

以下は、Hadoopが待ち受けていなくても動きますが、クラスがpublic宣言されていないのでソースを書きかえる必要がありました。

$ ~/hadoop-0.20.2/bin/hadoop jar mahout-examples-0.4.jar org.apache.mahout.clustering.display.DisplayCanopy

mahoutにGUIが付いていることは、意外にしられていないのでは、と思います。

火曜日, 12月 07, 2010

mahoutでTSP!

mahoutの中には、TSP(Travelling Salesman Problem / 巡回セールスマン問題)のが入っています。一応GUIも付いてます。でも、なぜかsrc版からコンパイルしないと動きません。


うーん。。地味。もっと派手なのかと思ったのですが(AWT入ってるからバイナリのやつだと動かないのかな)。ちなみにmahoutはTESTを回すと準備にかなり時間がかかるので、

$ mvn install -Dmaven.test.skip=true

とやるのが良いようです。そして以下で起動。
$ ~/hadoop-0.20.2/bin/hadoop jar examples/target/mahout-examples-0.4-job.jar org.apache.mahout.ga.watchmaker.travellingsalesman.TravellingSalesman

しかし、Hadoopでやらせる(チェックをつける)と、outputパスがもうあるから書けないよ!と文句を言われるのだけど、これはどうすればよいのだろう。
MahoutEvaluator.javaの中でoutputって定義してあるから、複数回(Generationの分だけ)この評価を回したら、そらバッティングすると思うんだけど。。?(これはHDFS上のホームディレクトリというか、/user/~/outputとかのようにできる)
このディレクトリを、ランダム文字列付きとして実行したら最後まで動くことは動いた。

なお、cygwinなどでローカル実行するときは、Generationを(デフォルトの100から)低い数字にしておかないと大変な時間がかかるので注意。

水曜日, 11月 10, 2010

rhinoから"Google Storage"にupload!

GSUtil というコマンドラインツールが用意されているものの、Python(?Rubyだっけ)なので使っていなかった、が、以下ソースでuploadに成功。
"WebOS Goodies"さんの情報を参考にしました。ありがとうございます!

importPackage(javax.crypto);
importPackage(javax.crypto.spec);
importPackage(org.apache.commons.codec.binary);

importPackage(org.apache.commons.httpclient);
importPackage(org.apache.commons.httpclient.methods);

var ACCESS_KEY = 'GOOG4C72MAOUMK7xxx3Z';
var SECRET     = 'xy4jTrxxxxuTZEtqUItfZIViVUF3xEKx4xxxp';
var HOST       = 'commondatastorage.googleapis.com';

var strDate    = getDate();
var strPath    = '/test/start.txt';

var headers = {
//  'Content-Length': '0',
'Content-Type': 'text/plain',
'Date': strDate,
    'User-Agent': 'Jakarta Commons-HttpClient/3.1',
    'Host': 'commondatastorage.googleapis.com'
};

// rhino + Java package/class
// http://d.hatena.ne.jp/terurou/20100918/1284791541

// http://www.fireproject.jp/feature/uzumi/httpclient/logging.html
java.lang.System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
java.lang.System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
java.lang.System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire.header", "debug");
java.lang.System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug");

var httpclient = new HttpClient();

if(false){ 
var httpget = new GetMethod("http://commondatastorage.googleapis.com" + strPath); 
httpget.setRequestHeader(new Header("Date",strDate));
httpget.setRequestHeader(new Header("Authorization",getAuthHeader('GET', headers,strPath)));

var statusCode = httpclient.executeMethod(httpget);  
print(httpget.getStatusLine());
}else{
var httpput = new PutMethod("http://commondatastorage.googleapis.com" + '/tf0054'+strPath);
var jstrTmp = "Hello this is a test in one line that is longer 12345677890\n";

httpput.setRequestHeader(new Header("Authorization",getAuthHeader('PUT', headers, strPath)));
httpput.setRequestHeader(new Header("Date",strDate));
httpput.setRequestHeader(new Header("x-goog-acl","public-read"));
httpput.setRequestHeader(new Header("Content-Type","text/plain"));
httpput.setRequestHeader(new Header("Content-Length","" + jstrTmp.length));
httpput.setRequestBody(jstrTmp);

httpclient.executeMethod(httpput);
print(httpput.getResponseBodyAsString());
}

function getAuthHeader(strMethod, headers, strPath){

function getHmacSign(strTmp){
var strType = 'HmacSHA1';
var jstrTmp = new java.lang.String(strTmp);
var jstrSec = new java.lang.String(SECRET);
var mac = Mac.getInstance(strType);
mac.init(new SecretKeySpec(jstrSec.getBytes(), strType));
return new java.lang.String(Base64.encodeBase64(mac.doFinal(jstrTmp.getBytes())),"UTF-8");
}

var strHeaders = strMethod + "\n";
strHeaders += "\n"; // Content-MD5 value
for(var i in headers){
if(i.toLowerCase() == 'date' || i.toLowerCase() == 'content-type'){
strHeaders += headers[i] + "\n";
} else {
// strHeaders += i.toLowerCase()+':'+headers[i]+"\r\n";
}
}
strHeaders += "x-goog-acl:public-read\n";
strHeaders += '/tf0054' + strPath;
print(">"+strHeaders);
return 'GOOG1 ' + ACCESS_KEY + ':' + getHmacSign(strHeaders);
}

function getDate(){
var d = new Date(new Date().getTime());
return d.toGMTString().replace(/UTC/,'GMT');
}

適当なソースですが、ご参考までに。

Twitter Updates

 
.