From: keiju@... (Keiju ISHITSUKA) Date: 1998-12-11T14:39:06+09:00 Subject: [ruby-list:11276] pstore.rb けいじゅ@日本ラショナルソフトウェアです. pstoreに関してですが, transactionをコミットしたあとでも @table の参照 が残ったままですよね? marshalした後, @table = nil とした方がよかないで すか? 今のままだと, @tableの内容がGCの対象になりません. そんでもって, いいの考えました. キャッシュ機能付きPStoreです. コミットした後, @tableの参照しているインスタンスをWeakRefを用いて保存 しておいて, 次にtransactionを開始した時に, GCされずに残っていたらそれ をそのまま使う方法です. こうすると, 読み込みのコストが下がる可能性が高くなっるのでよいと思いま せん? -- ここから # # How to use: # # db = PStoreWC.new("/tmp/foo") # db.transaction do # p db.roots # ary = db["root"] = [1,2,3,4] # ary[0] = [1,1.5] # end # db.transaction do # p db["root"] # end require "pstore" require "weakref" class PStoreWC < PStore def initialize(file) super @cache = nil end def transaction raise PStore::Error, "nested transaction" if @transaction begin @transaction = true value = file = nil if @cache and @cache.weakref_alive? @table = @cache[] else begin File::open(@filename, "r") do |file| @table = Marshal.load(file) end rescue Errno::ENOENT @table = {} end end begin catch(:pstore_abort_transaction) do value = yield(self) end rescue Exception @abort = true raise ensure unless @abort begin File::rename @filename, @filename+"~" rescue Errno::ENOENT no_orig = true end begin File::open(@filename, "w") do |file| Marshal::dump(@table, file) @cache = WeakRef.new(@table) end rescue File::rename @filename+"~", @filename unless no_orig end end @abort = false end ensure @transaction = false end value end end PSWC = PStoreWC if __FILE__ == $0 db = PStoreWC.new("/tmp/foo") db.transaction do p db.roots ary = db["root"] = [1,2,3,4] ary[0] = [1,1.5] end db.transaction do p db["root"] end ObjectSpace.garbage_collect db.transaction do p db["root"] end end __ ..............................石塚 圭樹@日本ラショナルソフトウェア... ----------------------------------->> e-mail: keiju@rational.com <<---