トップ «前の日記(2013-03-30) 最新 次の日記(2013-04-01)» 編集

ヨタの日々

2001|08|09|10|11|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|12|
2024|01|02|03|

2013-03-31 :-)

_ 午前

0930 起床

1030 おひる。梅うどん

1100 アニメ消化

_ 午後

1300 tumblr

1500 SC

_

2130 飯。塩鮭、じゃがいもとベーコンの煮ころがし

2230 mallc

_ ,

坂本真綾さんの誕生日です

_ [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はないわー」(意訳)と言っている。

sbrk - NetBSD Manual Pages

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は

  1. malloc
  2. pubrealloc
  3. imalloc
  4. 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