Class: BitClust::MethodSinceCalculator
- Defined in:
- lib/bitclust/method_since_calculator.rb
Overview
複数バージョンの DB(バージョンラダー)からメソッド名別の初出/削除 バージョンを算出し、対象 DB のメソッドエントリへ書き込む(bitclust#132 P2)。
ライブラリは意図的に無視する: 同じメソッドが版によって別ライブラリの 下でドキュメント化されていても、同一メソッドとして union で扱う。
算出値は「著者が明示した値(将来 P4 で since ... 等から記録される 想定)」より優先度が低い。#apply は MethodEntry#fill_since/fill_until を 使うため、既に値がある名前は上書きしない。
Instance Method Summary collapse
-
#apply(target_db) ⇒ Object
対象 DB の各メソッドエントリへ算出済みの since/until を書き込む。 target_db のバージョンはラダーに含まれていなければならない。 既に値がある名前は fill_since/fill_until の仕様により上書きされない (著者による明示値が算出値より優先される)。冪等: 2回目の apply は 何も変更しない(floor_skipped を除く).
-
#initialize(dbs) ⇒ MethodSinceCalculator
constructor
A new instance of MethodSinceCalculator.
-
#scan ⇒ Object
ラダーの各 DB を1つずつ走査して [クラス名, typechar, 生名] ごとの 初出/最終出現バージョンを記録する。走査済みの DB への参照は メモリを膨らませないようその場で捨てる.
-
#since_for(key) ⇒ Object
key = [クラス名, typechar, 生名]。ラダー最古版から存在する(フロア) 場合は「不明」を意味するので nil を返す.
-
#until_for(key) ⇒ Object
ラダー最新版でも存在する場合は「まだ削除されていない」ので nil。 そうでなければ最終出現バージョンの次のラダーバージョン(削除された版).
Constructor Details
#initialize(dbs) ⇒ MethodSinceCalculator
Returns a new instance of MethodSinceCalculator.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/bitclust/method_since_calculator.rb', line 21 def initialize(dbs) versions = dbs.map {|db| db.propget('version') } versions.each do |v| if v.nil? || v.empty? raise UserError, "database has no version property" end end dup = versions.tally.select {|_, n| n > 1 }.keys unless dup.empty? raise UserError, "duplicate version(s) in ladder: #{dup.join(', ')}" end sorted = dbs.sort_by {|db| Gem::Version.new(db.propget('version') || raise) } @versions = sorted.map {|db| db.propget('version') || raise } @ladder = sorted @first = {} #: Hash[key, String] @last = {} #: Hash[key, String] end |
Instance Method Details
#apply(target_db) ⇒ Object
対象 DB の各メソッドエントリへ算出済みの since/until を書き込む。 target_db のバージョンはラダーに含まれていなければならない。 既に値がある名前は fill_since/fill_until の仕様により上書きされない (著者による明示値が算出値より優先される)。冪等: 2回目の apply は 何も変更しない(floor_skipped を除く)
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/bitclust/method_since_calculator.rb', line 83 def apply(target_db) version = target_db.propget('version') unless @versions.include?(version) raise UserError, "#{version.inspect} is not one of the ladder versions: #{@versions.join(', ')}" end stats = {entries_updated: 0, since_filled: 0, until_filled: 0, floor_skipped: 0} #: stats target_db.classes.each do |c| c.entries.each do |m| next if m.kind == :undefined changed = false m.names.each do |name| key = [c.name, m.typechar, name] #: key if since_v = since_for(key) if m.fill_since(name, since_v) stats[:since_filled] += 1 changed = true end else stats[:floor_skipped] += 1 end if (until_v = until_for(key)) && m.fill_until(name, until_v) stats[:until_filled] += 1 changed = true end end if changed m.save stats[:entries_updated] += 1 end end end stats end |
#scan ⇒ Object
ラダーの各 DB を1つずつ走査して [クラス名, typechar, 生名] ごとの 初出/最終出現バージョンを記録する。走査済みの DB への参照は メモリを膨らませないようその場で捨てる
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/bitclust/method_since_calculator.rb', line 42 def scan ladder = @ladder or raise "scan was already called" @ladder = nil until ladder.empty? db = ladder.shift version = db.propget('version') || raise db.classes.each do |c| c.entries.each do |m| next if m.kind == :undefined m.names.each do |name| key = [c.name, m.typechar, name] #: key @first[key] ||= version @last[key] = version end end end end self end |
#since_for(key) ⇒ Object
key = [クラス名, typechar, 生名]。ラダー最古版から存在する(フロア) 場合は「不明」を意味するので nil を返す
64 65 66 67 |
# File 'lib/bitclust/method_since_calculator.rb', line 64 def since_for(key) first = @first[key] or return nil first == (@versions.first || raise) ? nil : first end |
#until_for(key) ⇒ Object
ラダー最新版でも存在する場合は「まだ削除されていない」ので nil。 そうでなければ最終出現バージョンの次のラダーバージョン(削除された版)
71 72 73 74 75 76 |
# File 'lib/bitclust/method_since_calculator.rb', line 71 def until_for(key) last = @last[key] or return nil return nil if last == (@versions.last || raise) idx = @versions.index(last) or raise "must not happen: #{last.inspect}" @versions[idx + 1] || raise end |