From: matz@... (Yukihiro Matsumoto) Date: 1998-09-25T13:12:46+09:00 Subject: [ruby-list:9722] Re: nif.rb (ver0.14) まつもと ゆきひろです In message "[ruby-list:9706] Re: nif.rb (ver0.14)" on 98/09/24, Yukihiro Matsumoto writes: ||といってもフルに機能を使ったわけではないので、適当なものを「これがOODB ||です」といって渡されればその機能の範囲内で納得してしまうかも。 | |lib/pstore.rbを渡して納得…できないでしょうね.o_dbm.rbの方 |では…やっぱり無理かなあ.o_dbm.rbの方はcontribにあります. pstore.rbはトランザクション毎に全部のデータをメモリに読み書 きするんでデータ量が増えるとだめでしょうね.ある程度の規模で も動作するdbmを使ったdstore.rbってのを作ってみました. こういうのが10分で作れるのがRubyの良いところですね. -- # # How to use: # # db = DStore.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 "marshal" require "dbm" class DStore class Error < StandardError end def initialize(file) @dbm = DBM.open(file) @transaction = false @filename = file @abort = false end def in_transaction raise Error, "not in transaction" unless @transaction end private :in_transaction def [](name) in_transaction value = @table[name] if value == nil value = @dbm[name] if value == nil raise Error, "undefined root name `%s'" % name end @table[name] = value = Marshal.load(value) end value end def []=(name, value) in_transaction unless name.kind_of? String raise TypeError, "root name should be String" end @table[name] = value end def roots in_transaction @dbm.keys end def root?(name) in_transaction @table.key? name or @dbm.key? name end def path @filename end def commit @abort = false throw :pstore_abort_transaction end def abort @abort = true throw :pstore_abort_transaction end def transaction raise Error, "nested transaction" if @transaction begin @transaction = true value = nil @table = {} begin catch(:pstore_abort_transaction) do value = yield(self) end rescue Exception @abort = true raise ensure for k, v in @table @dbm[k] = Marshal.dump(v) end @abort = false end ensure @transaction = false end value end end if __FILE__ == $0 db = DStore.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 end