2007/07/26

prototype.jsのハッシュキーに変数を利用する場合

通常、$Hでハッシュを利用する場合は以下のように
var h = $H({
'aaa' : 111,
'bbb' : 222,
});

と思いますがキーに変数を利用した場合は
var prmA = 'p1';
var prmB = 'p2';
var h = $H({
prmA : 111,
prmB : 222
});
とやりたいところですがこれだとキー名は「prmA」「prmB」
になってしまいます。eval等を利用してスクリプトとして全文字列を生成してから行っても
いいのですがちょっと面倒なので以下のように
var prmA = 'p1';
var prmB = 'p2';
var h = $H({});// ←new Object()ではダメ
h[prmA] = 111;
h[prmAB = 222;
とすることで簡単にできます。

2007/07/25

改行コードを
に変換する
改行コードには\r、\n、\r\nがあります。
それぞれ、OSなどによって差異があるわけですが、これを正規表現で「\r\nか\rか\n」という条件で
に変換します。
これはreplace(/\r\n|\r|\n/g,"
")で出来るわけですが、
http://tech.bayashi.net/pdmemo/chara.html
を参考に改行コード値(\r=\x0D、\n=\x0A、\r\n=\x0D\x0A)として変換します。
つまり、replace(/\x0D\x0A|\x0D|\x0A/g,"
")を使います。

CIでページキャッシュの拡張

CI付属のキャッシュ機能だとGETパラメータは省いたURLごとにキャッシュをする。
でも実際にはGETのパラメータも含めたURL毎にキャッシュすることが多いいのでコアライブラリを拡張する。拡張方法はCIのドキュメントをみてね。簡単にできますよ。

class MY_Output extends CI_Output {

function MY_Output()
{
parent::CI_Output();
log_message('debug', "MY_Output Class Initialized");
}

function _get_prm() {


if (isset($_GET) && count($_GET) != 0) {
$qryPrm = $_GET;

// IEのキャッシュ対策で時間をパラメーターとして付加している
// その部分のパラメータは考慮しない。「h」がキー
unset($qryPrm["h"]);
ksort($qryPrm);
return $qryPrm;
}
return "";
}

function _concatQryPrm($hm, $emptyExecFlg = true) {

$ret = null;

if ($hm == null || count($hm) == 0) {

return $ret;

}

$keys = array_keys($hm);
for ($cnt = 0; $cnt < count($keys); $cnt++) {

$key = $keys[$cnt];
if ($hm[$key] === null) {
if ($emptyExecFlg == false) {
continue;
}
}

if ($cnt == 0)
$ret .= $key . "=" . $hm[$key];
else
$ret .= "&" . $key . "=" . $hm[$key];

}

return $ret;

}



/**
* Write a Cache File
*
* @access public
* @return void
*/
function _write_cache($output)
{
$CI =& get_instance();
$path = $CI->config->item('cache_path');

$cache_path = ($path == '') ? BASEPATH.'cache/' : $path;

if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
{
return;
}

// $uri = $CI->config->item('base_url').
// $CI->config->item('index_page').
// $CI->uri->uri_string();

// GETパラメータも含める
$q = $this->_concatQryPrm($this->_get_prm());
$q = ($q == "" ? "" : "?" . $q);
$uri = $CI->config->item('base_url').
$CI->config->item('index_page').
$CI->uri->uri_string().
$q;

$cache_path .= md5($uri);

if ( ! $fp = @fopen($cache_path, 'wb'))
{
log_message('error', "Unable to write ache file: ".$cache_path);
return;
}

$expire = time() + ($this->cache_expiration * 60);

flock($fp, LOCK_EX);
fwrite($fp, $expire.'TS--->'.$output);
flock($fp, LOCK_UN);
fclose($fp);
@chmod($cache_path, 0777);

log_message('debug', "Cache file written: ".$cache_path);
}

// --------------------------------------------------------------------

/**
* Update/serve a cached file
*
* @access public
* @return void
*/
function _display_cache(&$CFG, &$RTR)
{
$CFG =& load_class('Config');
$RTR =& load_class('Router');

$cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');

if ( ! is_dir($cache_path) OR ! is_writable($cache_path))
{
return FALSE;
}

// Build the file path. The file name is an MD5 hash of the full URI
// $uri = $CFG->item('base_url').
// $CFG->item('index_page').
// $RTR->uri_string;

// GETパラメータも含める
$q = $this->_concatQryPrm($this->_get_prm());
$q = ($q == "" ? "" : "?" . $q);
$uri = $CFG->item('base_url').
$CFG->item('index_page').
$RTR->uri_string.
$q;

$filepath = $cache_path.md5($uri);

if ( ! @file_exists($filepath))
{
return FALSE;
}

if ( ! $fp = @fopen($filepath, 'rb'))
{
return FALSE;
}

flock($fp, LOCK_SH);

$cache = '';
if (filesize($filepath) > 0)
{
$cache = fread($fp, filesize($filepath));
}

flock($fp, LOCK_UN);
fclose($fp);

// Strip out the embedded timestamp
if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
{
return FALSE;
}

// Has the file expired? If so we'll delete it.
if (time() >= trim(str_replace('TS--->', '', $match['1'])))
{
@unlink($filepath);
log_message('debug', "Cache file has expired. File deleted");
return FALSE;
}

// Display the cache
$this->_display(str_replace($match['0'], '', $cache));
log_message('debug', "Cache file is current. Sending it to browser.");
return TRUE;
}


}

2007/07/24

PostgreSQLをチューニング

PostgreSQLをチューニングする機会があったので
その時に調べたチューニング項目を備忘録として残しておきます。
バージョンの違いやサーバの規模などによっても
効果は変わってくると思うのであくまで参考程度のものですが。

・shared_buffers
 7系では8000〜10000程度まで引き上げる
 8系では150000程度まで引き上げることが可能、100000程度が性能のピーク
 これに多く割り当てるよりOSのバッファ領域として使う方が性能が向上する
 テーブルサイズを割り出して設定するのがベスト
 簡単に設定するなら搭載メモリ量の1/4、搭載メモリが多ければ1/2ぐらいでも可
・max_connections
 7系では256程度、8系では1000程度が性能のピーク
・work_mem(sort_mem)
 適切なサイズに調整する、2048〜4096程度
 プロセス毎に領域が割り当てられるので多すぎるとスワップする可能性も
 ソートメモリはORDER BYだけではなくMerge Join、CREATE INDEX時でも使用される
・deadlock_timeout
 長めに設定する
 1000ms×同時セッション数が理想
・effective_cache_size
 数GBメモリ積んだマシンなら総メモリの1/4〜1/2を設定
・wal_buffers
 トランザクションが多い、大きい場合に多く取っておくと書き込み効率が良くなる。32〜64程度。
・commit_delay
 同時トランザクション数が多い場合、0以上を設定すると書き込み効率が上がる
・random_page_count
 余程巨大なテーブルが無い限り数GBのメモリのマシンなら2〜3が適当
・max_fsm_pages
 小さすぎるとクラスタ容量が増えすぎる、大きすぎると検索オーバーヘッドが大きくなる、vacuum -vの情報を見て調節
・bgwriter_maxpages
 参照系DBなら値を小さく、トランザクションが多いDBなら大きく設定する
・checkpoint_segments
 大きく設定するとハードディスクへの書き込み頻度が減り性能が向上する

・VACUUM FULLをしてもインデックスの領域は切り詰められないのでREINDEXを行い無駄な領域を削除する
・複数のハードディスク上のテーブルスペースにテーブルを作ることによりIOが分散し効率が良くなる
・walログも別ハードディスクに移すと結構IO効率が上がる
・fstabのマウント情報にnoatimeを指定し、atimeの更新を抑えると若干性能アップ

2007/07/12

PHPでUTF-8の文字数をShift-jisの文字数にてカウントする方法

$str = "12345あいうえお12345";
$str = mb_convert_encoding($str, "shift-jis", "UTF-8");
$str = mb_strcut($str, 0, 10, "shift-jis");
$str = mb_convert_encoding($str, "UTF-8", "shift-jis");
echo($str);
?>