9.27.2012

WebLogic Server: How to Get the File Descriptor Limit

WebLogic Server: FD上限の確認方法

WebLogic Server プロセスのFD(File Descriptor/ファイル記述子)数上限値を確認する3種類の方法。

1. WebLogic 起動時のサーバログを確認

$ grep BEA-000416 <サーバログ>
<main> <<WLS Kernel>> <> <BEA-000416> <Using effective file descriptor limit of: 1,024 open sockets/files.>

2. pfiles コマンドで確認

$ ps -ef | grep java    # WebLogicのプロセスIDを取得
$ pfiles <プロセスID> | grep rlimit
Current rlimit: 1024 file descriptors

pfiles コマンドは実行中プロセスをロックするので運用環境での実行は注意。

3. plimit コマンドで確認

$ ps -ef | grep java    # WebLogicのプロセスIDを取得
$ plimit <プロセスID>

参考:
https://blogs.oracle.com/imc/entry/weblogic_server_too_many_open

9.23.2012

Mac: How to Change Your Login Shell

Mac: ログインシェルの変更方法

OS X Mountain Lionの場合。

System Preferences -> Users & Groups

- 左下の鍵アイコン Click the lock to make changes. を選択
- ログインパスワードを入力し Unlock
- ユーザに対して右クリックし、Advanced Options… を選択
- Login shell を変更し OK 

Bitwise Operations in C++

TC++: ビット操作関連の関数

C++ でビット操作の実装。

・最右ビットの分離、最左ビットの分離(=2の冪乗で切り捨て)、1のビットの数を数えるコードと実行例

#include <cmath>
#include <iostream>
#include <ctime>

using namespace std;

// RMB(right-most bit)  : 01011000 => 00001000, 00000000 => 00000000
// LMB(left-most bit)   : 01011000 => 01000000, 00000000 => 00000000
// POP(population count): 01011000 => 3
template <typename T> T RMB(T x){return x&-(unsigned long long)x;}
unsigned int LMB32(unsigned int x){x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;return x-(x>>1);}
unsigned long long LMB(unsigned long long x){x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;x|=x>>32;return x-(x>>1);}
int POP32(unsigned x) {
  unsigned y=0x33333333;x-=(x>>1)&0x55555555;
  x=(x&y)+((x>>2)&y);x=(x+(x>>4))&0x0f0f0f0f;x+=x>>8;x+=x>>16;return x&0x3f;}
int POP(unsigned long long x) {
  unsigned long long y=0x3333333333333333ULL;x-=(x>>1)&0x5555555555555555ULL;
  x=(x&y)+((x>>2)&y);x=(x+(x>>4))&0x0f0f0f0f0f0f0f0fULL;x+=x>>8;x+=x>>16;x+=x>>32;return x&0x7f;}

#define sz(a) static_cast<int>(sizeof(a) / sizeof((a)[0]))
#define rep(i,n) for(int i=0;i<n;++i)
#define check32(val, name) \
  rep(i, sz(val)) { \
    printf("%s %08x: RMB=%08x, LMB=%08x, POP=%d\n", name, \
        val[i], RMB(val[i]), LMB32(val[i]), POP32(val[i])); \
  }
#define check64(val, name) \
  rep(i, sz(val)) { \
    printf("%s %016llx: RMB=%016llx, LMB=%016llx, POP=%d\n", name, \
        val[i], RMB(val[i]), LMB(val[i]), POP(val[i])); \
  }

int main(int argc, char *argv[]) {
  int ints[] = {0, 1, 88, 0x7fffffff, 0x80000000, 0xffffffff};
  unsigned uints[] = {0, 1, 88, 0x7fffffff, 0x80000000, 0xffffffff};
  long long lls[] = {0, 1, 88, 0x7fffffff, 0x80000000LL, 0xffffffffLL,
      0x7fffffffffffffffLL, 0x8000000000000000LL, 0xffffffffffffffffLL};
  unsigned long long ulls[] = {0, 1, 88, 0x7fffffff, 0x80000000LL, 0xffffffffLL,
      0x7fffffffffffffffLL, 0x8000000000000000LL, 0xffffffffffffffffLL};

  check32(ints , "int ");
  check32(uints, "uint");
  check64(lls  , "ll  ");
  check64(ulls , "ull ");
  return 0;
}

・実行結果

int  00000000: RMB=00000000, LMB=00000000, POP=0
int  00000001: RMB=00000001, LMB=00000001, POP=1
int  00000058: RMB=00000008, LMB=00000040, POP=3
int  7fffffff: RMB=00000001, LMB=40000000, POP=31
int  80000000: RMB=80000000, LMB=80000000, POP=1
int  ffffffff: RMB=00000001, LMB=80000000, POP=32
uint 00000000: RMB=00000000, LMB=00000000, POP=0
uint 00000001: RMB=00000001, LMB=00000001, POP=1
uint 00000058: RMB=00000008, LMB=00000040, POP=3
uint 7fffffff: RMB=00000001, LMB=40000000, POP=31
uint 80000000: RMB=80000000, LMB=80000000, POP=1
uint ffffffff: RMB=00000001, LMB=80000000, POP=32
ll   0000000000000000: RMB=0000000000000000, LMB=0000000000000000, POP=0
ll   0000000000000001: RMB=0000000000000001, LMB=0000000000000001, POP=1
ll   0000000000000058: RMB=0000000000000008, LMB=0000000000000040, POP=3
ll   000000007fffffff: RMB=0000000000000001, LMB=0000000040000000, POP=31
ll   0000000080000000: RMB=0000000080000000, LMB=0000000080000000, POP=1
ll   00000000ffffffff: RMB=0000000000000001, LMB=0000000080000000, POP=32
ll   7fffffffffffffff: RMB=0000000000000001, LMB=4000000000000000, POP=63
ll   8000000000000000: RMB=8000000000000000, LMB=8000000000000000, POP=1
ll   ffffffffffffffff: RMB=0000000000000001, LMB=8000000000000000, POP=64
ull  0000000000000000: RMB=0000000000000000, LMB=0000000000000000, POP=0
ull  0000000000000001: RMB=0000000000000001, LMB=0000000000000001, POP=1
ull  0000000000000058: RMB=0000000000000008, LMB=0000000000000040, POP=3
ull  000000007fffffff: RMB=0000000000000001, LMB=0000000040000000, POP=31
ull  0000000080000000: RMB=0000000080000000, LMB=0000000080000000, POP=1
ull  00000000ffffffff: RMB=0000000000000001, LMB=0000000080000000, POP=32
ull  7fffffffffffffff: RMB=0000000000000001, LMB=4000000000000000, POP=63
ull  8000000000000000: RMB=8000000000000000, LMB=8000000000000000, POP=1
ull  ffffffffffffffff: RMB=0000000000000001, LMB=8000000000000000, POP=64

・ アルゴリズム実測

LMB(最左のビットを求める計算)については、いくつかの異なるアプローチがある。

1) Divide & Conquer で 左端の1のビットを伝播させる。分岐不要。
2) 左端から1ビットずつ移動してチェック。 大きいビットが立っている場合に有利。
3) 最右の1のビットを消し込んでいく方法。1のビットが少ない場合に有利。
4) log2関数を使う方法。ただし、long long型の大きな数になると精度不足で誤った結果となってしまったので
 最初に一回だけ分岐を行った。

次のようなコードで実装した。

#include <cmath>
#include <iostream>
#include <ctime>

using namespace std;
typedef unsigned long long ULL;
#define sz(a) static_cast(sizeof(a) / sizeof((a)[0]))
#define rep(i,n) for(int i=0;i>i;return x-(x>>1);}

ULL LMB_BRANCH_FREE(ULL x) {rep(i,6)x|=x>>(1<<i);return x-(x>>1);}
ULL LMB_BRANCH_FREE2(ULL x) {x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;x|=x>>32;return x-(x>>1);}
ULL LMB_SHIFT(ULL x) {ULL y=0x8000000000000000;while(y>x)y>>=1;return y;}
ULL LMB_POP(ULL x) {ULL y;do{y=x;x=x&(x-1);}while(x);return y;}
ULL LMB_LOG2(ULL x) {ULL y=0x8000000000000000;return x&y?y:x?1ULL<<static_cast<int>(log2(x)):x;}

double time_it(int iter, int count, T func, U val) {
  double elapsed = 1e30;
  for (int i = 0; i < iter; ++i) {
    clock_t t = clock();
    for (int j = 0; j < count; ++j) {
      func(val);
    }
    clock_t s = clock();
    elapsed = min(elapsed, static_cast(s - t) / CLOCKS_PER_SEC);
  }
  return elapsed;
}

int main(int argc, char *argv[]) {
  ULL a[] = {0, 1, 0x6666666666666666ULL, 0x7fffffffffffffffULL, 0xffffffffffffffffULL};
  ULL (*f[])(ULL) = {LMB_BRANCH_FREE, LMB_BRANCH_FREE2, LMB_SHIFT, LMB_POP, LMB_LOG2};
  int iter = 3, count = 10000000;
  rep(i, sz(f)) rep(j, sz(a)) {
    printf("val=%016llx  elapsed=%.6f  count=%d  ret=%016llx\n",
        a[j], time_it(iter, count, f[i], a[j]), count, f[i](a[j]));
  }
}

手元のMacで実測した結果。

val=0000000000000000  elapsed=0.173500  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.169051  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.164456  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.162661  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=0.164984  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=0.104226  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.104737  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.104844  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.104384  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=0.104266  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=1.761051  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=1.732183  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.048205  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.048141  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=0.040281  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=0.049773  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.050759  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=1.017678  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=1.995849  count=10000000  ret=4000000000000000
val=ffffffffffffffff  elapsed=2.025537  count=10000000  ret=8000000000000000
val=0000000000000000  elapsed=0.049091  count=10000000  ret=0000000000000000
val=0000000000000001  elapsed=0.253222  count=10000000  ret=0000000000000001
val=6666666666666666  elapsed=0.233752  count=10000000  ret=4000000000000000
val=7fffffffffffffff  elapsed=0.233075  count=10000000  ret=8000000000000000
val=ffffffffffffffff  elapsed=0.044856  count=10000000  ret=8000000000000000

グラフにするとこんな感じ。当然ながら、ブランチフリー版が最も安定していた。
NewImage

9.17.2012

C++: 2D/3D Accumulator Class

C++: 2次元・3次元の累積和を求めるクラス

あるリストの特定区間の総和を繰り返し求める必要がある場合、更新が多いケースでは Binary Indexed Tree(BIT) が有効だ。
http://mogproject.blogspot.jp/2012/02/binary-indexed-tree-bit-in-c.html

ただし、更新は一度だけであとは参照するだけといった場合、単純な累積和テーブルを持たせれば計算量 Θ(1) で計算可能である。
これは、以下のように 2次元・3次元のリストにも適用できる。

区間の総和を求めるには、Inclusion–exclusion principle を利用する。
http://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle

・コード

template <typename T=int> class Acum2D {
public:
  Acum2D(int x, int y) {
    data_ = std::vector<std::vector<T> >(x + 1, std::vector<T>(y + 1, 0));
  }
  // must set values in ascending order
  void Set(int x, int y, T value) {
    data_[x + 1][y + 1] =
        value + data_[x][y + 1] + data_[x + 1][y] - data_[x][y];
  }
  // get the sum of data[x][y] such that:
  //     min_x <= x <= max_x and min_y <= y <= max_y
  T Get(int min_x, int min_y, int max_x, int max_y) const {
    if (min_x > max_x || min_y > max_y) return 0;
    ++max_x; ++max_y;
    return data_[max_x][max_y]-
        data_[min_x][max_y] - data_[max_x][min_y] + data_[min_x][min_y];
  }
private:
  std::vector<std::vector<T> > data_;
};

template <typename T=int> class Acum3D {
public:
  Acum3D(int x, int y, int z) {
    data_ = std::vector<std::vector<std::vector<T> > >(x + 1,
        std::vector<std::vector<T> >(y + 1, std::vector<T>(z + 1, 0)));
  }
  // must set values in ascending order
  void Set(int x, int y, int z, T value) {
    data_[x + 1][y + 1][z + 1] = value + data_[x][y + 1][z + 1] +
        data_[x + 1][y][z + 1] + data_[x + 1][y + 1][z] - data_[x][y][z + 1] -
        data_[x + 1][y][z] - data_[x][y + 1][z] + data_[x][y][z];
  }
  // get the sum of data[x][y][z] such that:
  //     min_x <= x <= max_x and min_y <= y <= max_y and min_z <= z <= max_z
  T Get(int min_x, int min_y, int min_z,
      int max_x, int max_y, int max_z) const {
    if (min_x > max_x || min_y > max_y || min_z > max_z) return 0;
    ++max_x; ++max_y; ++max_z;
    return data_[max_x][max_y][max_z] - data_[min_x][max_y][max_z] -
        data_[max_x][min_y][max_z] - data_[max_x][max_y][min_z] +
        data_[min_x][min_y][max_z] + data_[max_x][min_y][min_z] +
        data_[min_x][max_y][min_z] - data_[min_x][min_y][min_z];
  }
private:
  std::vector<std::vector<std::vector<T> > > data_;
};

・使用例

int data2d[5][3] = {{0, 1, 2}, {10, 11, 12}, {20, 21, 22}, {30, 31, 32}, {40, 41, 42}};
Acum2D<> acum2d(5, 3);
for (int i = 0; i < 5; ++i) for (int j = 0; j < 3; ++j) {
  acum2d.Set(i, j, data2d[i][j]);
}
// data[2][1] + data[2][2] + data[3][1] + data[3][2] + data[4][1] + data[4][2]
// = 21 + 22 + 31 + 32 + 41 + 42 = 189
std::cout << acum2d.Get(2, 1, 4, 2) << std::endl;

double data3d[3][3][3] = {
    {{ 0.0,  0.1,  0.2}, { 1.0,  1.1,  1.2}, { 2.0,  2.1,  2.2}},
    {{10.0, 10.1, 10.2}, {11.0, 11.1, 11.2}, {12.0, 12.1, 12.2}},
    {{20.0, 20.1, 20.2}, {21.0, 21.1, 21.2}, {22.0, 22.1, 22.2}},
};
Acum3D<double> acum3d(3, 3, 3);
for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) for (int k = 0; k < 3; ++k){
  acum3d.Set(i, j, k, data3d[i][j][k]);
}
// data[0][1][2] + data[0][2][2] + data[1][1][2] + data[1][2][2]
// = 1.2 + 2.2 + 11.2 + 12.2 = 26.8
std::cout << acum3d.Get(0, 1, 2, 1, 2, 2) << std::endl;

9.16.2012

Ubuntu: Keyboard Layout Reverting on Reboot

Ubuntu: 再起動するたびにキーボードレイアウトが元の状態に戻ってしまう

Ubuntu 10 で、例えば英語配列キーボードを使用している場合、キーボードレイアウトの設定で「日本語」を削除し
英語配列のみが有効な状態にする。

しかし、OSが再起動するとキーボードレイアウトの設定が復元され、再度「日本語」がデフォルトになってしまっている
という事象が発生した。

一旦ログアウトを行い、ログイン画面で以下の操作を行ったところ問題は解消した。

・ログインするユーザを選択
・パスワード入力の画面で画面下部のキーボードレイアウト(左から2番目のリスト)を適切なもの(今回の場合は英語)に設定
・パスワードを入力しログイン

参考:
https://bugs.launchpad.net/indicator-applet/+bug/688936

9.14.2012

C++: Froyd-Warshall Algorithm

C++: ワーシャルフロイド法の実装

アルゴリズム解説:
http://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm

コード:

// Froyd-Warshall Algorithm: O(|V| ^ 3)
template <typename T=int>
class FroydWarshall {
public:
  FroydWarshall(int num_nodes, T infinite=1000000001)
      : num_nodes_(num_nodes), infinite_(infinite) {
    data_ = std::vector<std::vector<T> >(
        num_nodes_, std::vector<T>(num_nodes, infinite_));
    for (int i = 0; i < num_nodes_; ++i) { data_[i][i] = 0; }
  }
  void MakeEdge(int from, int to, T weight) {
    data_[from][to] = weight;
  }
  void Update() {
    for (int k = 0; k < num_nodes_; ++k) {
      for (int i = 0; i < num_nodes_; ++i) {
        for (int j = 0; j < num_nodes_; ++j) {
          data_[i][j] = std::min(data_[i][j], data_[i][k] + data_[k][j]);
        }
      }
    }
  }
  bool IsReachable(int from, int to) { return data_[from][to] != infinite_; }
  std::vector<T> operator[](int from) { return data_[from]; }

private:
  std::vector<std::vector<T> > data_;
  int num_nodes_;
  T infinite_;
};

使用方法:

FroydWarshall<> g(100);
g.MakeEdge(0, 1, 10);
g.MakeEdge(1, 3, 20);
g.Update();  // must do this to calculate
std::cout << g.IsReachable(0, 2) << std::endl;  // print "0": cannot reach this vertex
std::cout << g.IsReachable(0, 3) << std::endl;  // print "1": can reach
std::cout << g[0][3] << std::endl;  // print "30": shortest path from vertex[0] to vertex[3]

9.11.2012

Eclipse: Problems During Content Assist

Eclipse: コンテンツアシストのエラー

MacマシンにSubclipseを導入した頃からであろうか、CDTでコンテンツアシストが走るたびに
以下のようなエラーが出るようになってしまった。

Screen Shot 2012 09 08 at 11 45 05 PM

mylyn プラグイン・Parsing-based Proposals (Task-Focused) で問題が発生しているようだが、プラグインを
削除したり、Parsing-based Proposals (Task-Focused)を無効にしても状況は改善しない。

結論としては、Eclipseの再インストールで直った。またこれを機に Eclipse 4.2 Juno へ乗り換えてみた。

備忘のため、再インストールの手順をメモしておく。

- 設定をバックアップ
 File -> Export…
 General -> Preferences を選択し Next
 Export all にチェック
 To preference file: に保存先のパスを入れて Finish

- /Applications/eclipse ディレクトリを削除

- Eclipse IDE for Java EE Developers MacOS X 64Bit をダウンロードして実行
 http://www.eclipse.org/downloads/ 

 前回は Eclipse IDE for C/C++ Developers を導入したが、今回は変えてみた。

- CDT のインストール
 Help -> Install New Software... 
 Work with: から Juno - http://download.eclipse.org/releases/juno を選択 
 Programming Language -> C/C++ Development Tools
                                              -> C/C++ Development Tools SDK
 を選択し、Next 以下手順にインストール。

- eclipse.ini の書き換え
 /Applications/eclipse/Eclipse.app/Contents/MacOS/eclipse.ini を編集し、ヒープサイズを増やす。
 今回はひとまず -Xmx512m を -Xmx1024m へ拡張。

- Scala IDE のインストール
 Scala IDE のインストール先は本来ならここなのだが、現行の 2.0.2 Release は Eclipse Juno に対応していない。
 http://scala-ide.org/download/current.html 

 Nightly バージョンの特別版をインストールする必要がある。
 http://scala-ide.org/download/nightly.html#scala_ide_helium_nightly_for_eclipse_42_juno 

 Help -> Install New Software... 
 Work with: に http://download.scala-ide.org/nightly-update-juno-master-29x を指定
 Scala IDE for Eclipse を選択し、Next 以下手順にインストール。

- Vrapper のインストール
 Help -> Install New Software... 
 Work with: http://vrapper.sourceforge.net/update-site/stable

 インストール後、~/.vrapperrc を適宜修正

- Subclipse のインストール
 Help -> Install New Software... 
 Work with: http://subclipse.tigris.org/update_1.8.x

- Marketplace Client のインストール
 Help -> Install New Software... 
 Work with: Juno - http://download.eclipse.org/releases/juno
 General Purpose Tools -> Marketplace Client 

- Eclipse Color Theme
 Help -> Eclipse Marketplace...
 "Eclipse Color Theme" で検索 

- 設定のインポート
 File -> Import... 
 General -> Preferences を選択し Next
 From preference file: に設定ファイルのパスを入力
 Import all にチェックして Finish

9.10.2012

Eclipse CDT Editor Color Settings

Eclipse: CDT エディタのカラー設定

Eclipse CDT(C/C++ Development Tools) を使っている場合、Eclipse Color Theme だけでは色が変わらない部分で文字が見えづらくなり、微調整が必要となることがある。

http://mogproject.blogspot.jp/2012/01/setting-eclipse-cdt-color-theme.html

この色の設定はどこなのか、と迷ってしまうことが多々あるので整理しておく。

- General -> Appearance -> Color Theme

  ここはカラーテーマを指定するだけ

Screen Shot 2012 09 10 at 3 36 46 AM

 

- General -> Appearance -> Colors and Fonts

  主にフォントを変えたい場合に利用
Screen Shot 2012 09 10 at 3 37 07 AM

- General -> Editors -> Text Editors

  現在行ハイライト、印刷マージン等を設定可能
Screen Shot 2012 09 10 at 3 37 28 AM

 

- General -> Editors -> Text Editors -> Annotations

  黒背景のテーマの場合、オカレンスの色を調整しないと目障りとなることが多い。
Screen Shot 2012 09 10 at 3 38 11 AM

- C/C++ -> Editor

  プリプロセッサによって無効化されたコードの背景色(Inactive code highlight)はここで指定する。
  これが一番分かりにくい場所だった。 
 Screen Shot 2012 09 10 at 3 38 37 AM

- C/C++ -> Editor -> Syntax Coloring

  シンタックスに応じた色の個別設定。

Screen Shot 2012 09 10 at 3 39 02 AM

 

9.07.2012

Vundle for Windows

Windows 環境で Vundle を使う

Vim プラグイン管理ツール Vundle を Windows マシンで使えるようにするためのメモ。

ここに従って作業を進める。
https://github.com/gmarik/vundle/wiki/Vundle-for-Windows

1. msysgit のインストール

 ここからダウンロード。
 http://code.google.com/p/msysgit/downloads/list
 途中で「Run Git from the Windows Command Prompt」を選択してパスを通す。

 コマンドプロンプトから、「git –-version」で稼働確認。

2. curl のセットアップ

 下記URLの内容を、{Git インストールディレクトリ}\cmd\curl.cmd として保存する。
 https://gist.github.com/912993

 コマンドプロンプトから、「curl -–version」で稼働確認。

3. Vumdle のセットアップ

 コマンドプロンプトから、以下のコマンドを実行と書いてある。(gvimにパスが通っている必要がある)

> cd %USERPROFILE%
> git clone http://github.com/gmarik/vundle.git .vim/bundle/vundle
> gvim _vimrc

 その後、こちらのステップが必要らしい。
 https://github.com/gmarik/vundle/blob/master/README.md

続きはまた後日。