2013-03-31 :-)
_ ,
坂本真綾さんの誕生日です
_ [tumblr]tumblr で reblog した画像を取得するだけの簡単なお仕事です
取得できる post に上限があるらしい。
Module: Tumblife::Client::Blog — Documentation for tumblife (1.3.0)
limit (Integer) - default: 20 - The number of posts to return: 1–20, inclusive
キャッシュに YAML とかないわー 上限が無いわー とかいろいろある。
#!/usr/bin/ruby # -*- encoding: utf-8 -*- require 'open-uri' require 'tumblife' require 'yaml' require 'pp' class Cache def initialize(cache_path) @path = cache_path read() end def read @cache = YAML.load_file(@path) if FileTest.file?(@path) @cache ||= [] end def write(contents) @cache << contents File.open(@path, "w").write(YAML.dump(contents)) end def include?(contents) return @cache.include?(contents) end end class Tumblove def initialize(config_path) @config = YAML.load_file(config_path) Tumblife.configure {|config| config.consumer_key = @config["api"]["consumer_key"] config.consumer_secret = @config["api"]["consumer_secret"] config.oauth_token = @config["api"]["oauth_token"] config.oauth_token_secret = @config["api"]["oauth_secret"] } @client = Tumblife.client @base_hostname = @config["post"]["host_name"] @cache = Cache.new(File.join(@config["cache"]["directory"], @config["cache"]["filename"])) end def downloaded?(uri) return @cache.include?(uri) end def downloaded(uri) @cache.write(uri) end def write(uri) return if downloaded?(uri) filename = File.join(@config["post"]["save_dir"], File.basename(uri)) open(filename, 'wb') {|outfile| open(uri) {|infile| outfile.write(infile.read) } } downloaded(uri) end def max_photos(post) photos ||= [] post.photos.each {|photo| max_size = 0 max_uri = '' photo.alt_sizes.each {|alt_size_photo| size = alt_size_photo.width if size > max_size max_size = size max_uri = alt_size_photo.url end } photos << max_uri } return photos end def get posts = @client.posts(@base_hostname) posts.posts.each {|post| next if post.photos == nil photos = max_photos(post) photos.each {|photo| write(photo) } } end end def main(argv) config_path = argv[0].nil? ? ENV['HOME'] + '/tumblr.yaml' : argv[0] t = Tumblove.new(config_path) t.get() end main(ARGV)
yaml を準備
cache: directory: ./ filename: tm_cache api: consumer_key: 'xxxx' consumer_secret: 'xxxx' oauth_token: 'xxxx' oauth_secret: 'xxxx' post: host_name: 'miwarin.tumblr.com'
実行
% ruby tm_get_image.rb tumblr.yaml
あとはこれを jenkins から呼び出すなど。
C:\cygwin\bin\ruby.exe C:\home\rin\work\lang\ruby\tumblr\tm_get_image.rb C:\home\rin\tumblr.yaml
post は最新 20 件しか取得できないのでとりあえずビルドトリガは @hourly を指定しておいた。
参考
_ [メモリ割り付け][sbrk][brk][malloc]malloc(3)
結局ライブラリ関数 malloc(3) はシステムコール sbrk(2) を呼び出す。
「詳解UNIXプログラミング」より
UNIXシステムでは、各システムコールに対して、同じ名前の関数を標準Cライブラリとして与える。ユーザープロセスは、Cの標準呼び出し系列を用いてこの関数を呼び出す。すると、この関数はシステムで必要とされる適切な技法を用いてカーネルサービスを起動する。例えば、関数では、Cの関数の引数を汎用レジスタに置いてから、カーネルに対してソフトウェア割り込みを発生させる機械語命令を実行する。(p.18)
メモリ割り付け関数mallocを例として考えよう。メモリ割り付けとそのガーベージコレクションには(ベストフィット、ファーストフィットなどの)多くの方式がある。メモリ割り付けを処理するUNIXのシステムコールはsbrk(2)だが、これは汎用メモリ管理機構ではない。プロセスのアドレス空間をい指定したバイト数だけ増減する。この空間をどのように管理するかは、プロセスの責任である。メモリ割り付け関数mallocは、1つの特定の割り付け方式を実現する。この方式に不満ならばs,独自のmalloc関数を定義できるが、sbrkシステムコールは使うだろう。(p.19
NetBSD マニュアル。「21世紀にもなってsbrkはないわー」(意訳)と言っている。
The brk and sbrk functions are legacy interfaces from before the advent of modern virtual memory management.
i386 の実装はこちら。アセンブラなので誰でも読めます。
malloc 実装はいろいろある。
FreeBSD 7.0 以降と NetBSD 5.0 以降では、古い実装 (phkmalloc) を Jason Evans が開発した jemalloc に置換した。phkmalloc はマルチスレッド環境でのスケーラビリティに問題があった。ロックの衝突を防ぐため、jemalloc はCPU毎に分離した "arena" と呼ばれる領域を用意する。
NetBSD の malloc と jemalloc はこちら。C言語なので誰でも読めます。
mallocは
- malloc
- pubrealloc
- imalloc
- malloc_bytes
と呼ばれ、確保したメモリを page_dir にリンクリストとして繋げていくらしい。
struct pginfo { struct pginfo *next; /* next on the free list */ void *page; /* Pointer to the page */ u_short size; /* size of this page's chunks */ u_short shift; /* How far to shift for this size chunks */ u_short free; /* How many free chunks */ u_short total; /* How many chunk */ u_int bits[1]; /* Which chunks are free */ };
jemalloc は誰かがんばって (´Д`;)
4894713195