新規作成
OpenIDで認証してエントリーを新規作成します
共有
エントリーにはOpenIDで閲覧と編集に制限かけることができます
変更履歴
編集履歴もあるので、コラボレーションにも活用できます

Cache::Memcached::Fastをmemcached 1.4.0でのprotocol変更に対応させる

memcached1.4.0でdeleteのprotocolが変わった

とりあえず、Cache::Memcached::Fastが大きく影響を受けるのでpatchを書いてみる。


明示的にdelayを設定する(おそらく1.4.0を使ってない)場合だけ、deleteコマンドにtimeを付けます。

diff --git a/src/client.c b/src/client.c
index 7d84ffe..7ab41cf 100644
--- a/src/client.c
+++ b/src/client.c
@@ -2011,8 +2011,13 @@ client_prepare_delete(struct client *c, int key_index,
 
   {
     char *buf = array_end(c->str_buf, char);
-    size_t str_size =
-      sprintf(buf, " " FMT_DELAY "%s\r\n", delay, get_noreply(state));
+    size_t str_size;
+
+    if ( delay )
+      str_size = sprintf(buf, " " FMT_DELAY "%s\r\n", delay, get_noreply(state));
+    else
+      str_size = sprintf(buf, "%s\r\n", get_noreply(state));
+
     iov_push(state, (void *) (long) array_size(c->str_buf), str_size);
     array_append(c->str_buf, str_size);
   }

このpatchをあてることで、とりあえずnoreplyのdeleteが正しく動くようになります

created by blog.nomadscafe.jp

memcached 1.4.0でdeleteのprotocolが変わった

ので、noreplyでのdeleteが動かない件

あとでblog書く


memcached 1.4.0からdeleteのtimeoutがなくなったので、

delete key [<time>] [noreply]

だったのが、

delete key [noreply]

となった。

see http://github.com/memcached/memcached/commit/5da8dbab2a815c00617ab60b641391ada8d96f40#diff-2


Cache::Memcached::Fastだと、timeoutに0を常にいれてしまうので、

noreply時に死ぬ。(noreplyじゃない場合のtimeoutはmemcached側で無視してくれる)


## check script

#!/usr/bin/perl -l
use strict;
use Cache::Memcached::Fast;

my $cache = Cache::Memcached::Fast->new({
            servers => [{address=>"127.0.0.1:11212",noreply=>1}]
            });
$cache->set('key1','val1');
$cache->set('key2','val2');

# is fail
$cache->delete('key1');

print 'failed get key2' unless $cache->get('key2');
print 'can get key1' if $cache->get('key1');

#実行結果

% perl aa.pl 
failed get key2
can get key1

## memcached log

% ./memcached -vv -p 11212
<32 new auto-negotiating client connection
32: Client using the ascii protocol
<32 set key1 0 0 4 noreply
>32 NOREPLY STORED
<32 set key2 0 0 4 noreply
>32 NOREPLY STORED
<32 delete key1 0 noreply
>32 ERROR
<32 get key2
>32 sending key key2
>32 END
<32 connection closed.
<32 new auto-negotiating client connection
32: Client using the ascii protocol
<32 get key1
>32 sending key key1
>32 END
<32 connection closed.
created by blog.nomadscafe.jp

test

test

created by http://tenjin-q12.coara.or.jp/identity/takasugi

平成21年6月28日(日)

今日は雨と天気予報では言っていたが晴れている。

created by http://tenjin-q12.coara.or.jp/identity/abeken

ダブルキャスト エンド10ルート

ダマそうと…

生年月日

名前


ラーメン屋

あっそ…

気をつけないと


主演女優の

どうする?

ナイト様

どうしたんだ!

怒るぞ!

友達が来てて


話題をかえよう

友達だよ

ハイ!!

部長と一緒が


外の空気

顔は見た?

もう少しセリフ


熱いお茶

風呂!?


逃げよう

created by wired-lynx.net

WWW::MobileCarrierJP::DoCoMo::Display。VGAモード対応案

案にもなってない

ちょっと変えた@20090610

diff --git a/lib/WWW/MobileCarrierJP/DoCoMo/Display.pm b/lib/WWW/MobileCarrierJP/DoCoMo/Display.pm
index ae4310f..b5d1510 100644
--- a/lib/WWW/MobileCarrierJP/DoCoMo/Display.pm
+++ b/lib/WWW/MobileCarrierJP/DoCoMo/Display.pm
@@ -13,17 +13,27 @@ sub scrape {
     $html =~ s/(?:\r?\n)+/\n/g;
     $html =~ s/&mu;/myu/g;
     my $re = _regexp();
+    my $opt_re = _opt_regexp();
+    chomp $opt_re;
     my $map;
     while ( $html =~ /$re/igs ) {
-        my ( $model, $width, $height, $color, $depth ) = ( $1, $2, $3, $4, $5 );
-
-        push @$map, {
+        my ( $model, $width, $height, $opt, $color, $depth ) = ( $1, $2, $3, $4, $5, $6 );
+        my %ret = (
             model    => $model,
             width    => $width,
             height   => $height,
             is_color => $color eq 'カラー',
             depth    => $depth,
-        };
+        );
+
+        my ($vga_width, $vga_height) = ( '', '' );
+        if ( $opt =~ /$opt_re/is ) {
+            $ret{vga_width} = $width;
+            $ret{vga_height} = $height;
+            $ret{width} = $1;
+            $ret{height} = $2;
+        }
+        push @$map, \%ret;
     }
     $map;
 }
@@ -46,11 +56,18 @@ sub _regexp {
 <td><span class="txt">.*?(?:</span></td>)?
 <td><span class="txt">.*?(?:</span></td>)?
 <td><span class="txt">.*?(\d+)×(\d+).*?</span></td>
-<td>.*?</td>
+(<td>.*?</td>)
 <td><span class="txt">(白黒|カラー)(?:.*?)(\d+)(?:色|階調)</span></td>
 RE
 }
 
+sub _opt_regexp {
+    return <<'RE';
+<td><span class="txt">.*?(\d+)×(\d+).*?</span></td>
+<td>.*?</td>
+RE
+}
+
 1;
 __END__
 
diff --git a/t/020_docomo/03_docomo_displaymap.t b/t/020_docomo/03_docomo_displaymap.t
index a7591de..0931d82 100644
--- a/t/020_docomo/03_docomo_displaymap.t
+++ b/t/020_docomo/03_docomo_displaymap.t
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 6;
+use Test::More tests => 7;
 use WWW::MobileCarrierJP::DoCoMo::Display;
 
 my $dat = WWW::MobileCarrierJP::DoCoMo::Display->scrape;
@@ -25,6 +25,16 @@ ck(
     width    => 240,
 );
 
+ck(
+    depth    => 16777216,
+    height   => 296,
+    is_color => 1,
+    model    => 'SH-05A',
+    width    => 240,
+    vga_width => 480,
+    vga_height => 592,
+);
+
 sub ck {
     my $phone = @_ == 1 ? $_[0] : {@_};
     is_deeply [grep { $phone->{model} eq $_->{model} } @$dat]->[0], $phone;
created by blog.nomadscafe.jp

Cache::Memcached::Fast 0.14を以前のketama algorithmにも対応させる

ketamaの分散を改善するために、全バージョンとアルゴリズムの互換性がなくなったことで有名なCache::Memcache::Fast 0.14ですが以前のアルゴリズムへも対応できるようにpatchつくってみました。


使い方

my $memcached = Cache::Memcached::Fast->new({
    servers => [qw/127.0.0.1:11222 127.0.0.1:11223/],
    old_ketama_algo => 1,
    ketama_points => 150,
});

patch

diff -ur Cache-Memcached-Fast-0.14.orig/Fast.xs Cache-Memcached-Fast-0.14/Fast.xs
--- Cache-Memcached-Fast-0.14.orig/Fast.xs        2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/Fast.xs     2009-05-14 15:12:35.000000000 +0900
@@ -207,6 +207,10 @@
 
   memd->servers = newAV();
 
+  ps = hv_fetch(conf, "old_ketama_algo", 15, 0);
+  if (ps && SvOK(*ps))
+    client_set_old_ketama_algo(c, SvTRUE(*ps));
+
   ps = hv_fetch(conf, "ketama_points", 13, 0);
   if (ps && SvOK(*ps))
     {
diff -ur Cache-Memcached-Fast-0.14.orig/lib/Cache/Memcached/Fast.pm Cache-Memcached-Fast-0.14/lib/Cache/Memcached/Fast.pm
--- Cache-Memcached-Fast-0.14.orig/lib/Cache/Memcached/Fast.pm    2009-02-07 20:34:56.000000000 +0900
+++ Cache-Memcached-Fast-0.14/lib/Cache/Memcached/Fast.pm 2009-05-14 13:35:40.000000000 +0900
@@ -508,6 +508,7 @@
     max_failures => 1,
     failure_timeout => 1,
     ketama_points => 1,
+    old_ketama_algo => 1,
     serialize_methods => 1,
     utf8 => 1,
     max_size => 1,
diff -ur Cache-Memcached-Fast-0.14.orig/src/client.c Cache-Memcached-Fast-0.14/src/client.c
--- Cache-Memcached-Fast-0.14.orig/src/client.c   2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/client.c        2009-05-14 15:13:12.000000000 +0900
@@ -293,6 +293,7 @@
   int failure_timeout;          /* 1 sec.  */
   int close_on_error;
   int nowait;
+  int old_ketama_algo;
   int hash_namespace;
 
   struct array index_list;
@@ -398,6 +399,7 @@
   c->failure_timeout = 10;
   c->close_on_error = 1;
   c->nowait = 0;
+  c->old_ketama_algo = 0;
   c->hash_namespace = 0;
 
   c->generation = 1;            /* Different from initial command state.  */
@@ -512,6 +514,11 @@
   c->nowait = enable;
 }
 
+void
+client_set_old_ketama_algo(struct client *c, int enable)
+{
+    c->old_ketama_algo = enable;
+}
 
 void
 client_set_hash_namespace(struct client *c, int enable)
@@ -542,7 +549,7 @@
     return res;
 
   res = dispatch_add_server(&c->dispatch, host, host_len, port, port_len,
-                            weight, array_size(c->servers));
+                            weight, array_size(c->servers), c->old_ketama_algo);
   if (res == -1)
     return MEMCACHED_FAILURE;
 
diff -ur Cache-Memcached-Fast-0.14.orig/src/client.h Cache-Memcached-Fast-0.14/src/client.h
--- Cache-Memcached-Fast-0.14.orig/src/client.h   2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/client.h        2009-05-14 16:22:08.000000000 +0900
@@ -155,6 +155,10 @@
 
 extern
 void
+client_set_old_ketama_algo(struct client *c, int enable);
+
+extern
+void
 client_reset(struct client *c, struct result_object *o, int noreply);
 
 extern
diff -ur Cache-Memcached-Fast-0.14.orig/src/dispatch_key.c Cache-Memcached-Fast-0.14/src/dispatch_key.c
--- Cache-Memcached-Fast-0.14.orig/src/dispatch_key.c     2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/dispatch_key.c  2009-05-14 15:29:36.000000000 +0900
@@ -158,7 +158,7 @@
 ketama_crc32_add_server(struct dispatch_state *state,
                         const char *host, size_t host_len,
                         const char *port, size_t port_len,
-                        double weight, int index)
+                        double weight, int index, int old_ketama_algo)
 {
   static const char delim = '\0';
   unsigned int crc32, point;
@@ -184,10 +184,19 @@
         We want the same result on all platforms, so we hardcode size
         of int as 4 8-bit bytes.
       */
-      buf[0] = point & 0xff;
-      buf[1] = (point >> 8) & 0xff;
-      buf[2] = (point >> 16) & 0xff;
-      buf[3] = (point >> 24) & 0xff;
+      if ( old_ketama_algo ) {
+          point = 0;
+          buf[0] = i & 0xff;
+          buf[1] = (i >> 8) & 0xff;
+          buf[2] = (i >> 16) & 0xff;
+          buf[3] = (i >> 24) & 0xff;
+      }
+      else {
+          buf[0] = point & 0xff;
+          buf[1] = (point >> 8) & 0xff;
+          buf[2] = (point >> 16) & 0xff;
+          buf[3] = (point >> 24) & 0xff;
+      }
 
       point = compute_crc32_add(crc32, buf, 4);
 
@@ -284,11 +293,11 @@
 dispatch_add_server(struct dispatch_state *state,
                     const char *host, size_t host_len,
                     const char *port, size_t port_len,
-                    double weight, int index)
+                    double weight, int index, int old_ketama_algo)
 {
   if (state->ketama_points > 0)
     return ketama_crc32_add_server(state, host, host_len, port, port_len,
-                                   weight, index);
+                                   weight, index, old_ketama_algo);
   else
     return compatible_add_server(state, weight, index);
 }
diff -ur Cache-Memcached-Fast-0.14.orig/src/dispatch_key.h Cache-Memcached-Fast-0.14/src/dispatch_key.h
--- Cache-Memcached-Fast-0.14.orig/src/dispatch_key.h     2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/dispatch_key.h  2009-05-14 13:45:45.000000000 +0900
@@ -60,7 +60,7 @@
 dispatch_add_server(struct dispatch_state *state,
                     const char *host, size_t host_len,
                     const char *port, size_t port_len,
-                    double weight, int index);
+                    double weight, int index, int old_ketama_algo);
 
 extern
 int
created by blog.nomadscafe.jp

Variable::Magic と Tie::Scalar

なんとなくやってみた

package TestTie;

use strict;
use warnings;
require Tie::Scalar;
use vars qw/@ISA/;
@ISA = qw/Tie::StdScalar/;

sub FETCH { 123 }

package main;

use strict;
use warnings;
use Variable::Magic qw/wizard cast/;
use Benchmark;

tie my $tied, 'TestTie', 123;
warn $tied;

my $wiz = wizard get => sub  { ${$_[0]} = 123 };
my $magic;
cast $magic, $wiz;
warn $magic;

Benchmark::cmpthese(3000000, {
    'tie' => sub { my $foo = $tied * 123 },
    'magic' => sub { my $foo = $magic * 123 },
});

結果

% perl tie.pl
123 at tie.pl line 21.
123 at tie.pl line 26.
          Rate   tie magic
tie   426136/s    --  -20%
magic 531915/s   25%    --
created by blog.nomadscafe.jp

Tracのソースビュアーで文字コードを自動判定する

ヤマロぶろぐ : Tracでファイルの文字コードを自動判定 - livedoor Blog(ブログ)Python でエンコーディングを判定する - 傀儡師の館.Python - 楽天ブログ(Blog)あたりを参考にして入れてみた。

chardetだとあまり判定が良くなかったのでpykf使ってみた

--- api.py.orig 2009-05-01 11:41:16.000000000 +0900
+++ api.py      2009-05-01 12:35:32.000000000 +0900
@@ -71,6 +71,21 @@
 from trac.util.text import to_utf8, to_unicode
 from trac.util.translation import _
 
+# For charset detection.
+CHARSET_RE = re.compile(r'coding[=:]\s*(\S+)')
+
+try:
+    # http://archives.sertice.org/devs/linux/cvs/pykf-0.3.4.tgz
+    import pykf
+    pykf.setdefault(pykf.EUC)
+    pykf.setstrict(True)
+    PYKF_ENC = {pykf.UNKNOWN:None, pykf.ASCII:'ASCII', 
+        pykf.SJIS:'SHIFT-JIS',  pykf.EUC:'EUC-JP',
+        pykf.JIS:'ISO-2022-JP', pykf.UTF8:'UTF-8',
+        pykf.UTF16:'utf-16', pykf.UTF16_BE:'utf-16_be',
+        pykf.ERROR:None}
+except ImportError:
+    pass
 
 __all__ = ['get_mimetype', 'is_binary', 'detect_unicode', 'Mimeview',
            'content_to_unicode', 'Context']
@@ -824,6 +839,15 @@
             utf = detect_unicode(content)
             if utf is not None:
                 return utf
+
+            m = CHARSET_RE.search(content, 0, 200)
+            if m:
+                return m.group(1)
+
+            if 'pykf' in globals():
+                encoding = PYKF_ENC[pykf.guess(content)]
+                if encoding != 'None':
+                    return encoding
         return self.default_charset
 
     def get_mimetype(self, filename, content=None):

なにげに初python

created by blog.nomadscafe.jp

Image::JpegCheckのpatch

ちょっと足りない事があるので、

--- Image-JpegCheck-0.02.orig/t/01_simple.t     2009-04-24 13:45:02.000000000 +0900
+++ Image-JpegCheck-0.02/t/01_simple.t  2009-04-24 12:57:56.000000000 +0900
@@ -1,11 +1,13 @@
 use strict;
 use warnings;
-use Test::More tests => 4;
+use Test::More tests => 6;
 use Image::JpegCheck;
 
 is is_jpeg('t/foo.jpg'), 1;
+is is_jpeg('t/bar.jpg'), 1;
 is is_jpeg('t/01_simple.t'), 0;
 test_fh('t/foo.jpg', 1);
+test_fh('t/bar.jpg', 1);
 test_fh('t/01_simple.t', 0);
 
 sub test_fh {
--- Image-JpegCheck-0.02.orig/lib/Image/JpegCheck.pm    2009-04-24 12:48:54.000000000 +0900
+++ Image-JpegCheck-0.02/lib/Image/JpegCheck.pm 2009-04-24 13:40:18.000000000 +0900
@@ -38,8 +38,15 @@
     return 0 if $buf ne MAGICK;
 
     while (1) {
-        read($fh, $buf, 4);
-        ($marker, $code, $len) = unpack("a a n", $buf); # read segment header
+        read($fh, $buf, 2);
+        ($marker, $code) = unpack("a a", $buf); # read segment header
+
+        while ( $code eq SECTION_MARKER && ($marker = $code) ) {
+            read($fh, $buf, 1);
+           ($code) = unpack("a", $buf);
+       }
+       read($fh, $buf, 2);
+       $len = unpack( "n", $buf );
         $code = ord($code);
 
         if ($marker ne SECTION_MARKER) {

XSは修正していません

created by blog.nomadscafe.jp

<234567891011>