2010-06-23 一万億兆京垓𥝱穣溝澗正載極恒河沙阿僧祇那由他不可思議
億とか京とか
ruby | |
Ruby-listのMLで流れていた、[ruby-list:47175] 金額を漢字フォーマット 億, 千, 万を見て、汎用的に「n桁で区切っていく接頭辞系」を作れないかなと思って試しにやってみた。
#!/usr/bin/ruby -Ku # -*- coding: utf-8 -*- Units = [ "" , "万", "億", "兆", "京", "垓", "禾予", "穣", "溝", "澗", "正", "載", "極", "恒河沙", "阿僧祇", "那由他", "不可思議", "無量大数"] Digit_per_unit = 4 def to_jp_unit(num) str = num.to_s r_ary = str.split(//).reverse result_ary = Array.new buf = Array.new is_empty = true # zero skip flag r_ary.each do |digit| buf.unshift(digit) is_empty &&= (digit == "0") if buf.length >= Digit_per_unit if is_empty result_ary.unshift("") else result_ary.unshift("#{buf}#{Units[result_ary.length]}") end buf.clear is_empty = true end end if buf.length > 0 result_ary.unshift("#{buf}#{Units[result_ary.length]}") end result_str = "" result_ary.each{|part| result_str += part } return result_str end while(line=gets) do num = line.to_i puts "#{num} -> #{to_jp_unit(num)}" end
'Digit_per_unit'で区切る桁数を、Unitsに接頭辞を列挙。Digit_per_unitを3にして、Unitsに"K,M,G,T,P,..."とやれば、SI接頭辞に。
…3(SI接頭辞)と4(命数法)しか思いつかないけど。
実際に万億兆...とやりたい場合は、↑のURLでやってる方法が早いんじゃないかと思います。思いついたままにコーディングしてるので、逆順配列作ったり作業用配列作ったりしてるので遅いはず。
追記
投稿してから気づいたけど、こうすりゃもっとシンプルでした。
def to_jp_unit2(num) num_str = num.to_s target_digits = num_str.split(//).length unit_count = (target_digits / Digit_per_unit).to_i unit_count.downto(0) do |i| regexp_str = "([1-9]\\d{0,3})(\\d{#{i*Digit_per_unit}})$" replace_to = "\\1#{Units[i]}\\2" num_str.sub!(Regexp.new(regexp_str), replace_to) end num_str.gsub!(/(\D)0+/, '\1') return num_str end
2010-06-13 それシェルでできるよ
あるディレクトリにある全てのファイルの内容を置換する
d:id:d-kami:20100613を見て、それ別にRuby使わなくてもシェルで、しかも一行でできるよ、と思ったので書いておく。
原理はカンタン、対象となるファイルをfindでリストアップして、xargsで他のコマンドに渡すだけ。
sedコマンドは、"-i"オプションでファイルに対して破壊的な変更を行うことができる。なので、一度別のファイルにはき出して元のファイルを削除してリネーム、なんてことも必要ない。
$ find . -name '対象ファイルパターン' -print0 | xargs -0 sed -i '置換正規表現'
具体的には、こんな感じ。
$ cat dir1/hello.txt hello d_kami! bye, d_kami! $ cat third_dir/haro-.txt haro- d_kami! baibai d_kami... $ find . -name '*.txt' -print0 | xargs -0 sed -i 's/d_kami/yas/g' $ cat dir1/hello.txt hello yas! bye, yas! $ cat third_dir/haro-.txt haro- yas! baibai yas...
やはり、yaslinuxの基本コマンド群は偉大である。
2010-06-10 今日もRubyちゃんとちゅっちゅ
IPアドレスを扱う
ruby | |
IPアドレス・サブネット関係の処理が必要になったので調べた。
"IPAddr"クラスを使うようだ。そのメモ。
irb(main):001:0> require 'pp' => true irb(main):002:0> require 'ipaddr' => true irb(main):003:0> ipaddr1 = IPAddr.new("192.168.0.3") => #<IPAddr: IPv4:192.168.0.3/255.255.255.255> irb(main):004:0> ipaddr2 = IPAddr.new("192.168.0.103") => #<IPAddr: IPv4:192.168.0.103/255.255.255.255> # 素直に文字列としてIPアドレスを渡してやればOK irb(main):005:0> ipaddr1 == ipaddr2 => false # 単純な比較 irb(main):006:0> masked = ipaddr1.mask("255.255.255.0") => #<IPAddr: IPv4:192.168.0.0/255.255.255.0> # 既存のオブジェクトに、指定したネットマスクを適用したオブジェクトを取得 irb(main):007:0> masked.include?(ipaddr1) => true irb(main):008:0> masked.include?(ipaddr2) => true irb(main):009:0> ipaddr3 = IPAddr.new("192.168.1.3") => #<IPAddr: IPv4:192.168.1.3/255.255.255.255> irb(main):010:0> masked.include?(ipaddr3) => false # ネットマスク付きオブジェクトに含まれるかどうかをinclude?で取得 # ネットマスク付きオブジェクトを作るときは、↓こうじゃなくて irb(main):011:0> range = IPAddr.new("172.16.0.5","255.255.0.0") ArgumentError: address family unmatch from /usr/lib/ruby/1.8/ipaddr.rb:436:in `initialize' from (irb):11:in `new' from (irb):11 # ↓こうする。aaa.bbb.ccc.ddd/www.xxx.yyy.zzz 形式か、aaa.bbb.ccc.ddd/xx 形式を使う。 irb(main):012:0> range = IPAddr.new("172.16.0.5/255.255.0.0") => #<IPAddr: IPv4:172.16.0.0/255.255.0.0> irb(main):013:0> ipaddr4 = IPAddr.new("172.16.100.200") => #<IPAddr: IPv4:172.16.100.200/255.255.255.255> irb(main):014:0> range.include?(ipaddr4) => true irb(main):015:0> range.include?(ipaddr1) => false
2010-05-31 続・ぶいぶいぶいっ
V-Fieldを使ってみた
linux | |
りべんじ。
前回のエントリについて
前回(d:id:syonbori_tech:20100530)はコンパイルに成功したところまで。そこでいくつか修正を行ったが、それがあってるかどうか不安だったので、@frsyukiに聞いてみた。
どうやら、"-static"はgccへの指定で、スタティックリンクライブラリを指定する物らしい。"-static -lboost_thread-mt" とした場合、libboost_thread-mt.aがリンクされるらしい。Fedora12でyumを使ってboostをインストールする場合、.soしかインストールされないため、エラーとなっていたようだ。
とりあえず、"-Bstatic"でも動いているが、念のため補足。
足りないパッケージをインストール
nbdが必要だった。さくっとインストーる。
# yum install nbd
V-FIELDを使ってみる
PC1とPC2の環境を用意して、PC1上にファイルを用意して、PC2から参照してみる。
PC1(最初に提供する側)
動作確認のため非デーモンモードで動作させる。
$ ./vfield -file /tmp/random_10MB -if eth0 -nodaemon RootStorage is initialized with /tmp/random_10MB (10485760 bytes) Stream is listened on aaa.bbb.ccc.ddd:19660 RPC is listened on any:19660 NBD is listened on 127.0.0.1:8990
どうやらRPCに19660/TCPを使うようだ。
PC2(見に行く側)
こちらも非デーモンモードで動作させる。vfieldを実行するターミナルと、nbd-clientでマウント?を行うターミナルの二つが必要。
$ ./vfield -bs aaa.bbb.ccc.ddd -store 1 -nodaemon Storage layer is initialized with 1048576 bytes limit Stream is listened on aaa.bbb.ccc.ddd:19660 RPC is listened on any:19660 NBD is listened on 127.0.0.1:8990 Stream Join succeeded, image size is 10485760 bytes Storing data range is 7340032 - 8388607
"-store"で指定するのは、自分が保持する容量らしい。
そして、もう一枚のターミナルでnbd-clientを実行する。こちらにはroot権限が必要なようだ。
# nbd-client localhost 8990 /dev/nbd0 Negotiation: ..size = 10240KB bs=1024, sz=10240
これで、/dev/nbd0 にPC1のファイルがマウントされる。
vfield側には次のような表示がされていた。
Storing data is successfully downloaded NBD negotiation successed
ためしにのぞいてみる。
# hexdump -C /dev/nbd0 | head -n 10 00000000 50 e4 50 d0 99 8f e3 35 1b 42 b8 e1 93 f8 5f 41 |P.P....5.B...._A| 00000010 83 0b 78 6d e0 de 61 39 71 3d 05 5e 04 32 d7 d2 |..xm..a9q=.^.2..| 00000020 38 af a4 04 0e 51 62 d5 7f 64 db b8 67 02 d6 11 |8....Qb..d..g...| 00000030 87 40 69 ef ac 81 ac 56 82 58 12 6f 3d 5c 71 a6 |.@i....V.X.o=\q.| 00000040 02 e7 4b d2 9d 76 f4 a2 f6 20 4c 76 22 c1 c2 43 |..K..v... Lv"..C| 00000050 e7 24 d2 2f 98 19 32 22 6f 59 ea a5 47 54 f6 4e |.$./..2"oY..GT.N| 00000060 03 f5 60 20 a5 a7 a8 0d 96 fe 20 2a df 2b 91 25 |..` ...... *.+.%| 00000070 64 a2 6e 60 a9 88 ec 5f 30 2b af 88 03 84 37 d4 |d.n`..._0+....7.| 00000080 53 c6 0b 95 0e b8 b6 ab 9b 4b 91 a6 49 76 ab ab |S........K..Iv..| 00000090 5f e8 56 6e 12 39 66 56 6c 56 98 2e cd 5b 26 60 |_.Vn.9fVlV...[&`|
PC1側のものと一致したことを確認。
性能
VirtualBox上のゲストでやってるのでアテになりません…(´・ω・`)
2010-05-30 ぶいぶいぶいっ
V-Fieldを使ってみたい
linux | |
読み取り専用の分散多重化共有ブロックデバイス、V-FIELD(V-FIELD - VIVER)を使ってみたようとした。
環境
Fedora12, x86_64, V-FIELD changeset 69
下準備
レポジトリへのアクセスにmercurial、コンパイルにimake, boostが必要なのでインストーる。
# yum install mercurial imake boost boost-devel
レポジトリからソースコードを取得
$ mkdir /usr/src/vfield $ cd /usr/src/vfield $ hg clone http://viver.sourceforge.jp/cgi-bin/repos/vfield.cgi destination directory: vfield.cgi requesting all changes adding changesets adding manifests adding file changes added 70 changesets with 815 changes to 121 files updating to branch default 68 files updated, 0 files merged, 0 files removed, 0 files unresolved
vfield.cgiディレクトリ以下にコピーされる。
boostの変更に追従
boost/thread.hppをincludeするのではなく、boost/thread/condition.hppをincludeする必要があるらしい。
影響のあるファイルは
$ grep -R 'boost::condition' * common/locked_queue.h: boost::condition m_cond; common/rw_lock.h: boost::condition m_final; common/notify.h: boost::condition cond; common/threadpool.h: boost::condition ring_cond; search/engine.cc: boost::condition m_condition; stream/stream.cc: boost::condition m_sweep_thread_cond;
この6ファイルらしい。これらにincludeを追加する。
また、boost_threadがマルチスレッド用にboost_thread-mtと名前が変わっているので、あわせてRules.mkも変更する。
次のパッチファイルを使って一括更新する。
diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/Rules.mk vfield.cgi.new/Rules.mk --- vfield.cgi/Rules.mk 2010-05-31 00:06:30.888090400 +0900 +++ vfield.cgi.new/Rules.mk 2010-05-31 00:57:27.121144254 +0900 @@ -1,5 +1,5 @@ CXX ?= c++ -OPTIMIZE = -O5 -mtune=pentium4 +OPTIMIZE = RELEASE = $(OPTIMIZE) -DNDEBUG QUIET = $(OPTIMIZE) -DQUIET QUIET0 = $(OPTIMIZE) -DQUIET0 @@ -7,7 +7,7 @@ #CFLAGS += -Wall -g -pipe -I$(build_dir) -I$(build_dir)/common -D_FILE_OFFSET_BITS=64 $(RELEASE) CFLAGS += -Wall -pipe -I$(build_dir) -I$(build_dir)/common -D_FILE_OFFSET_BITS=64 $(RELEASE) #LDFLAGS += -lpthread -Wl,-Bstatic -lboost_thread -Wl,-Bdynamic -lrt -LDFLAGS += -static -lboost_thread -lpthread -lrt +LDFLAGS += -Bstatic -lboost_thread-mt -lpthread -lrt .SUFFIXES: .cc .o .h .h.gch .exe diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/common/locked_queue.h vfield.cgi.new/common/locked_queue.h --- vfield.cgi/common/locked_queue.h 2010-05-31 00:06:30.903091653 +0900 +++ vfield.cgi.new/common/locked_queue.h 2010-05-31 00:05:51.113101332 +0900 @@ -5,6 +5,7 @@ #include <queue> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> +#include <boost/thread/condition.hpp> // XXX: 例外処理が無い diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/common/notify.h vfield.cgi.new/common/notify.h --- vfield.cgi/common/notify.h 2010-05-31 00:06:30.906093691 +0900 +++ vfield.cgi.new/common/notify.h 2010-05-31 00:05:44.132098662 +0900 @@ -4,6 +4,7 @@ #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> #include <boost/thread.hpp> +#include <boost/thread/condition.hpp> //#include <boost/bind.hpp> //#include <functional> diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/common/rw_lock.h vfield.cgi.new/common/rw_lock.h --- vfield.cgi/common/rw_lock.h 2010-05-31 00:06:30.907093439 +0900 +++ vfield.cgi.new/common/rw_lock.h 2010-05-31 00:05:47.598124341 +0900 @@ -2,6 +2,7 @@ #define VFIELD_RW_LOCK_H__ #include <boost/thread.hpp> +#include <boost/thread/condition.hpp> #include <boost/utility.hpp> namespace VFIELD { diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/common/threadpool.h vfield.cgi.new/common/threadpool.h --- vfield.cgi/common/threadpool.h 2010-05-31 00:06:30.909090980 +0900 +++ vfield.cgi.new/common/threadpool.h 2010-05-31 00:05:39.931339695 +0900 @@ -6,6 +6,7 @@ #include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_deque.hpp> #include <boost/thread.hpp> +#include <boost/thread/condition.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> // 使う側で便利用 diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/search/engine.cc vfield.cgi.new/search/engine.cc --- vfield.cgi/search/engine.cc 2010-05-31 00:06:30.931102485 +0900 +++ vfield.cgi.new/search/engine.cc 2010-05-31 00:05:34.131130781 +0900 @@ -16,6 +16,7 @@ #include <functional> #include <boost/bind.hpp> #include <boost/ptr_container/ptr_vector.hpp> +#include <boost/thread/condition.hpp> namespace VFIELD { diff -Nur --exclude=Makefile --exclude=Makefile.bak --exclude=.hg vfield.cgi/stream/stream.cc vfield.cgi.new/stream/stream.cc --- vfield.cgi/stream/stream.cc 2010-05-31 00:06:30.942272674 +0900 +++ vfield.cgi.new/stream/stream.cc 2010-05-31 00:05:19.169104287 +0900 @@ -14,6 +14,7 @@ #include <deque> #include <algorithm> #include <boost/thread.hpp> +#include <boost/thread/condition.hpp> #include <boost/bind.hpp> #include <boost/shared_array.hpp> #include <boost/scoped_ptr.hpp>
こんなファイルを、vfield.cgi と同じディレクトリに、cond-boost_thread.patch として作成し、次のようにして適用する。
$ patch -p0 < cond-boost_thread.patch patching file vfield.cgi/Rules.mk patching file vfield.cgi/common/locked_queue.h patching file vfield.cgi/common/notify.h patching file vfield.cgi/common/rw_lock.h patching file vfield.cgi/common/threadpool.h patching file vfield.cgi/search/engine.cc patching file vfield.cgi/stream/stream.cc
makeする
$ make depend
大量のwarningが出てもとりあえず気にしない。
$ make
が通れば(どうやら)OK。
予想以上に手間取ったので今日はここまで。。。