TortoiseSVNのログをhogehogeする

TortoiseSVNの以下のinputのような情報を自由に処理したい.
例えば、outputのように対象のファイルが修正されたRevisionを出力するなど...
とりあえず、コードは動く. 寝ます.

[input]
Revision: 1
Author: xxx
Date: xxx
Message:
I am very tired..

      • -

Modified : /piopio.java

Revision: 2
....

[output]
target: piopio.java
rev: 1, 3, 5

[code]

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * @author dki
 *
 */
public class TargetRevisionFomatter {

	
	private static String TAG_REV = "Revision:";
	private static String TAG_AUTH = "Author:";
	private static String TAG_DATE = "Date:";
	private static String TAG_MESS = "Message:";
	private static String TAG_OTHER = "----";

	private static Pattern PAT_REV = Pattern.compile(TAG_REV);
	private static Pattern PAT_AUTH = Pattern.compile(TAG_AUTH);
	private static Pattern PAT_DATE = Pattern.compile(TAG_DATE);
	private static Pattern PAT_MESS = Pattern.compile(TAG_MESS);
	private static Pattern PAT_OTHER = Pattern.compile(TAG_OTHER);

	private static Pattern PAT_MOD = Pattern.compile("Modified");
	private static Pattern PAT_ADD = Pattern.compile("Added");
	private static Pattern PAT_DELL = Pattern.compile("Deleted");
	
	private Map<Integer, Map<String, List<String>>> contants = new HashMap<Integer, Map<String, List<String>>>();

	private static enum READ_STATE{
		REV, AUTH, DATE, MESS, OTHER, NONE
	}
	private READ_STATE state = null;

	private READ_STATE whichTAG(String line){
		if(PAT_REV.matcher(line).find()){
			return READ_STATE.REV;
		}else if(PAT_AUTH.matcher(line).find()){
			return READ_STATE.AUTH;
		}else if(PAT_DATE.matcher(line).find()){
			return READ_STATE.DATE;
		}else if(PAT_MESS.matcher(line).find()){
			return READ_STATE.MESS;
		}else if(PAT_OTHER.matcher(line).find()){
			return READ_STATE.OTHER;
		}else{
			return READ_STATE.NONE;
		}

	}

	public void parseContants(File file) throws IOException{

		BufferedReader br = new BufferedReader(new FileReader(file));

		String str = br.readLine();
		int counter = 0;

		while(str != null){

			READ_STATE line_state = whichTAG(str);
			
			if(state==null && line_state==READ_STATE.NONE){
				str = br.readLine();
				continue;
			}

			//System.out.println(str);
			if(line_state == READ_STATE.REV){
				contants.put(++counter, new HashMap<String, List<String>>());
			}

			if(line_state != READ_STATE.NONE){
				state = line_state;
				
				String regex = ".+: (.*)";
				Pattern p = Pattern.compile(regex);
				Matcher m = p.matcher(str);
				if (m.find()){
					addVal(counter, m.group(1));
				}
			}else{
				addVal(counter, str);
			}

		    str = br.readLine();
		}
	}
	
	private void addVal(int index, String val){
		List<String> vals = contants.get(index).get(state.toString());
		if(vals == null){
			vals = new ArrayList<String>();
			contants.get(index).put(state.toString(), vals);
		}
		vals.add(val);
	}
	
	public void printTarget2Rev(){
		Map<String, List<Integer>> target2revMap = new HashMap<String, List<Integer>>();
		for(Entry<Integer, Map<String, List<String>>> e :contants.entrySet()){
			Map<String, List<String>> commitLog = e.getValue();
			for(String target:commitLog.get(READ_STATE.OTHER.toString())){
				List<Integer> revlist = target2revMap.get(target);
				if(revlist==null){
					revlist = new ArrayList<Integer>();
				}
				revlist.add(Integer.valueOf(commitLog.get(READ_STATE.REV.toString()).get(0)));
				target2revMap.put(target, revlist);
			}
		}
		
		for(Entry<String, List<Integer>> e:target2revMap.entrySet()){
			String target = e.getKey();
			if(PAT_MOD.matcher(target).find()){
				String[] ss = target.split("/");
				System.out.print("m " + ss[ss.length-1]);
			}else if(PAT_ADD.matcher(target).find()){
				String[] ss = target.split("/");
				System.out.print("+ " + ss[ss.length-1]);
			}else if(PAT_DELL.matcher(target).find()){
				String[] ss = target.split("/");
				System.out.print("- " + ss[ss.length-1]);
			}
			
			System.out.print(",");
			
			List<Integer> revs = e.getValue();
			Collections.sort(revs);
			for(Integer rev:revs){
				System.out.print(rev );
			}
			
			System.out.println(", " + target);
		}
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		
		TargetRevisionFomatter inst = new TargetRevisionFomatter();
		inst.parseContants(new File("branch.log"));
		inst.printTarget2Rev();
		
	}

}

fetchのパフォーマンス

JavaFireBirdへfetchするパフォーマンスを改善する必要があるのでそのメモ.

  • ポイント(?)

- SQLレベル
  複雑なqueryではないので、改善の余地なし?
- Schemaレベル
  政治的に変えられない?
- Java上での扱い方
  ここに着目

以下、情報のまとめ.

  • Stored Proceduresの利用

 - SQL文の送信と前処理が必要なく、 クライアントからの問い合わせよりも高速に処理することができます。
 - http://www.technotype.net/tutorial/tutorial.php?fileId={SQL}§ionId={what-is-stored-procedure}

  • select * from Tablexyz を使用するより必要なカラムだけを select [1]

- 通信量が減るため?

  • Statement や ResultSet オブジェクトをできるだけ直に close[1]

- 理由は不明

  • 多量のデータの読み込み専用のクエリについて:データの操作、格納のアクセスの媒介としてEJB Objectを使用することを避け、JavaBeansを使用しなさい。[1]
  • ResultSet から余分なカラムを除きなさい[1]

[1] http://www002.upp.so-net.ne.jp/tomo008/J2EE_Performance/JDBC_Performance_Tips.html

その他、覚えておきたいこと

  • Batch Update

- 複数の更新処理(insert, update, delete)をまとめて実行する機能

  • 少なくない行を検索する場合、ResultSet.next() はデータベースから行をfetchするためにかなり多くの時間を要する。この時間はデータベースアクセスの測定時間に含めるべきである。[1]
  • avoid a-way database joins: join は倍数的に性能に影響を及ぼす。このパフォーマンスの低下は大きなデータセットが含まれる際には顕著に表れる。[1]
  • 何千もの行を取得することを避ける。[1]

- 代替案は?

#ここまで

ffmpegのPixel Formatsの定数値

ffmpegを利用してコードを書くときに必要だったのでprintfで出力した。
そのメモ。

PIX_FMT_NONE:     -1
PIX_FMT_YUV420P: 0
PIX_FMT_YUYV422: 1
PIX_FMT_RGB24:     2
PIX_FMT_BGR24: 3
PIX_FMT_YUV422P: 4
PIX_FMT_YUV444P: 5
PIX_FMT_YUV410P: 6
PIX_FMT_YUV411P: 7
PIX_FMT_GRAY8: 8
PIX_FMT_MONOWHITE: 9
PIX_FMT_MONOBLACK: 10
PIX_FMT_PAL8: 11
PIX_FMT_YUVJ420P: 12
PIX_FMT_YUVJ422P: 13
PIX_FMT_YUVJ444P: 14
PIX_FMT_XVMC_MPEG2_MC: 15
PIX_FMT_XVMC_MPEG2_IDCT:16
PIX_FMT_UYVY422: 17
PIX_FMT_UYYVYY411: 18
PIX_FMT_BGR8: 19
PIX_FMT_BGR4: 20
PIX_FMT_BGR4_BYTE: 21
PIX_FMT_RGB8: 22
PIX_FMT_RGB4: 23
PIX_FMT_RGB4_BYTE: 24
PIX_FMT_NV12: 25
PIX_FMT_NV21: 26
PIX_FMT_ARGB: 27
PIX_FMT_RGBA: 28
PIX_FMT_ABGR: 29
PIX_FMT_BGRA: 30
PIX_FMT_GRAY16BE: 31
PIX_FMT_GRAY16LE: 32
PIX_FMT_YUV440P: 33
PIX_FMT_YUVJ440P: 34
PIX_FMT_YUVA420P: 35
PIX_FMT_VDPAU_H264: 36
PIX_FMT_VDPAU_MPEG1: 37
PIX_FMT_VDPAU_MPEG2: 38
PIX_FMT_VDPAU_WMV3: 39
PIX_FMT_VDPAU_VC1: 40
PIX_FMT_RGB48BE: 41
PIX_FMT_RGB48LE: 42
PIX_FMT_RGB565BE: 43
PIX_FMT_RGB565LE: 44
PIX_FMT_RGB555BE: 45
PIX_FMT_RGB555LE: 46
PIX_FMT_VAAPI_MOCO: 51
PIX_FMT_VAAPI_IDCT: 52
PIX_FMT_VAAPI_VLD: 53
PIX_FMT_NB: 60


念のため, 環境を記載。

FFmpeg version SVN-r19750, Copyright (c) 2000-2009 Fabrice Bellard, et al.
configuration: --enable-memalign-hack --extra-cflags=-fno-common --enable-shar
ed --enable-gpl
libavutil 50. 3. 0 / 50. 3. 0
libavcodec 52.34. 0 / 52.34. 0
libavformat 52.38. 0 / 52.38. 0
libavdevice 52. 2. 0 / 52. 2. 0
libswscale 0. 7. 1 / 0. 7. 1
built on Sep 1 2009 19:39:38, gcc: 4.2.1-sjlj (mingw32-2)
At least one output file must be specified

LIBSVMのMATLAB用ソースをoctaveで使う

Learning the Discriminative Power-Invariance Trade-Off
http://research.microsoft.com/en-us/um/people/manik/projects/trade-off/trade-off.html
MATLAB用のコードがとりあえずcygwin上でoctaveで動いた。
手順を忘れないようにメモ。


<準備>
1.コードの取得
http://research.microsoft.com/en-us/um/people/manik/code/GMKL/libsvm-2.84.tgz
からダウンロード。


2.octave(version 3.2.4)のインストール
cygwinのstart.exeから
Math/octave, Math/octave-devel, Math/octave-doc, Math/octave-forge
をインストール。


3.fftw3のインストール
コードのコンパイルの際に必要になった。
cygwinのstart.exeからMath/libfftw3-develをインストール。



コンパイル
MEXファイルを作り, octaveからコードの関数を呼び出せるようにする。
MatlabOctaveのファイルの位置関係が分からなかったのでMakefileの内容
を頼りに行った。


webで以下のような記述も見つけたが対応したLIBSVMMakefileoctaveのターゲットは見つからなかった。
http://www.google.co.jp/url?q=http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html%23f805&usg=AFQjCNGhpHLyyhhH6Sr0GGgT8wAE9g6gtg&sa=X&ei=Io4QTNHIFc_IcaG9lfwH&ved=0CBwQygQ


1.cygwinでA−1のCode/libsvm-2.84-1のディレクトリに移動


2.ソースの変更
以下をコメントアウトした。
read_sparse.c://typedef int mwIndex;
svm_model_matlab.c://typedef int mwIndex;
svmpredict.c://typedef int mwIndex;
svmtrain.c://typedef int mwIndex;


3.svm_model_matlab.oの作成
$gcc -I/usr/include/octave-3.2.4/octave -c svm_model_matlab.c


4.octaveの起動
$ octave --braindead


5.svmpredict.mex, svmtrain.mex, read_sparse.mexの作成
>> mex --mex svmpredict.c svm.o svm_model_matlab.o
>> mex --mex svmtrain.c svm.o svm_model_matlab.o
>> mex --mex read_sparse.c



<動作確認>
1.コードに付属しているREADMEのExamplesの一部を実行
>> load heart_scale.mat
>> model = svmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 2');
>> [predict_label, accuracy, dec_values] = svmpredict(heart_scale_label, heart_scale_inst, model);
Accuracy = 99.2593% (268/270) (classification)

cvCompareHistのCV_COMP_INTERSECTの仕様

openCVで実装されている, ヒストグラム間の距離を求める関数cvCompareHistが良く分からなかったので調べてみた。

具体的に分からなかった点は, 第3引数でCV_COMP_INTERSECTを指定したときの仕様と距離の持つ意味。

ソースを確認ところ, 仕様は
http://opencv.willowgarage.com/documentation/histograms.html?highlight=cvcomparehist#cvCompareHist [1]
に記載されている通り。

d(H1,H2)=sumImin(H1(I),H2(I))

ただし, min(a,b) = a (if a

else if( method == CV_COMP_INTERSECT )
{
for( i = 0; i < len; i++ )
result += std::min(h1[i], h2[i]);
}

この距離がどういう意味を持つかは後日考えて見ます。



<メモ>

  • ninosekiさんの「ニノ日記」

http://d.hatena.ne.jp/ninoseki/20090208より抜粋。

Learning OpenCVによると、速さを求める場合にはIntersection、正確さを求める場合にはBhattacharyya distanceかChi-squareを用いるのがいいとのこと。