diff options
author | Tom Gilbert <tom@linuxbrit.co.uk> | 2006-01-27 18:32:35 +0000 |
---|---|---|
committer | Tom Gilbert <tom@linuxbrit.co.uk> | 2006-01-27 18:32:35 +0000 |
commit | 6a606e8d5b485b578b9fcbe23f5e1fb5210f491f (patch) | |
tree | f32656c8447242b180c4406909b52451fea98b46 /lib/rbot | |
parent | 780cdd54ea51ad7d388e2a4dd386cf02d477c083 (diff) |
autosplit registry. now we have one per plugin.
TODO creates empty dbs for plugins that don't even use the registry. would
be nice to only create on write but how feasible is that?
Diffstat (limited to 'lib/rbot')
-rw-r--r-- | lib/rbot/registry.rb | 115 |
1 files changed, 56 insertions, 59 deletions
diff --git a/lib/rbot/registry.rb b/lib/rbot/registry.rb index 2a7edbb6..6afc7622 100644 --- a/lib/rbot/registry.rb +++ b/lib/rbot/registry.rb @@ -2,19 +2,13 @@ require 'rbot/dbhash' module Irc - # this is the backend of the RegistryAccessor class, which ties it to a - # DBHash object called plugin_registry(.db). All methods are delegated to - # the DBHash. + # this class is now used purely for upgrading from prior versions of rbot + # the new registry is split into multiple DBHash objects, one per plugin class BotRegistry def initialize(bot) @bot = bot upgrade_data - @db = DBTree.new @bot, "plugin_registry" - end - - # delegation hack - def method_missing(method, *args, &block) - @db.send(method, *args, &block) + upgrade_data2 end # check for older versions of rbot with data formats that require updating @@ -23,13 +17,13 @@ module Irc def upgrade_data if File.exist?("#{@bot.botclass}/registry.db") puts "upgrading old-style (rbot 0.9.5 or earlier) plugin registry to new format" - old = BDB::Hash.open "#{@bot.botclass}/registry.db", nil, + old = BDB::Hash.open("#{@bot.botclass}/registry.db", nil, "r+", 0600, "set_pagesize" => 1024, - "set_cachesize" => [0, 32 * 1024, 0] - new = BDB::CIBtree.open "#{@bot.botclass}/plugin_registry.db", nil, + "set_cachesize" => [0, 32 * 1024, 0]) + new = BDB::CIBtree.open("#{@bot.botclass}/plugin_registry.db", nil, BDB::CREATE | BDB::EXCL | BDB::TRUNCATE, 0600, "set_pagesize" => 1024, - "set_cachesize" => [0, 32 * 1024, 0] + "set_cachesize" => [0, 32 * 1024, 0]) old.each {|k,v| new[k] = v } @@ -38,7 +32,37 @@ module Irc File.delete("#{@bot.botclass}/registry.db") end end + + def upgrade_data2 + if File.exist?("#{@bot.botclass}/plugin_registry.db") + Dir.mkdir("#{@bot.botclass}/registry") + dbs = Hash.new + puts "upgrading previous (rbot 0.9.9 or earlier) plugin registry to new split format" + old = BDB::CIBtree.open("#{@bot.botclass}/plugin_registry.db", nil, + "r+", 0600, "set_pagesize" => 1024, + "set_cachesize" => [0, 32 * 1024, 0]) + old.each {|k,v| + prefix,key = k.split("/", 2) + prefix.downcase! + unless dbs.has_key?(prefix) + puts "creating db #{@bot.botclass}/registry/#{prefix}.db" + dbs[prefix] = BDB::CIBtree.open("#{@bot.botclass}/registry/#{prefix}.db", + nil, BDB::CREATE | BDB::EXCL | BDB::TRUNCATE, + 0600, "set_pagesize" => 1024, + "set_cachesize" => [0, 32 * 1024, 0]) + end + dbs[prefix][key] = v + } + old.close + File.rename("#{@bot.botclass}/plugin_registry.db", "#{@bot.botclass}/plugin_registry.db.old") + dbs.each {|k,v| + puts "closing db #{k}" + v.close + } + end + end end + # This class provides persistent storage for plugins via a hash interface. # The default mode is an object store, so you can store ruby objects and @@ -86,19 +110,12 @@ module Irc class BotRegistryAccessor # plugins don't call this - a BotRegistryAccessor is created for them and # is accessible via @registry. - def initialize(bot, prefix) + def initialize(bot, name) @bot = bot - @registry = @bot.registry - @orig_prefix = prefix - @prefix = prefix + "/" + @name = name.downcase + @registry = DBTree.new bot, "registry/#{@name}" @default = nil - # debug "initializing registry accessor with prefix #{@prefix}" - end - - # use this to chop up your namespace into bits, so you can keep and - # reference separate object stores under the same registry - def sub_registry(prefix) - return BotRegistryAccessor.new(@bot, @orig_prefix + "+" + prefix) + # debug "initializing registry accessor with name #{@name}" end # convert value to string form for storing in the registry @@ -122,7 +139,7 @@ module Irc def restore(val) begin Marshal.restore(val) - rescue + rescue Exception $stderr.puts "failed to restore marshal data, falling back to default" if @default != nil begin @@ -138,8 +155,8 @@ module Irc # lookup a key in the registry def [](key) - if @registry.has_key?(@prefix + key) - return restore(@registry[@prefix + key]) + if @registry.has_key?(key) + return restore(@registry[key]) elsif @default != nil return restore(@default) else @@ -149,7 +166,7 @@ module Irc # set a key in the registry def []=(key,value) - @registry[@prefix + key] = store(value) + @registry[key] = store(value) end # set the default value for registry lookups, if the key sought is not @@ -161,40 +178,34 @@ module Irc # just like Hash#each def each(&block) @registry.each {|key,value| - if key.gsub!(/^#{Regexp.escape(@prefix)}/, "") - block.call(key, restore(value)) - end + block.call(key, restore(value)) } end # just like Hash#each_key def each_key(&block) @registry.each {|key, value| - if key.gsub!(/^#{Regexp.escape(@prefix)}/, "") - block.call(key) - end + block.call(key) } end # just like Hash#each_value def each_value(&block) @registry.each {|key, value| - if key =~ /^#{Regexp.escape(@prefix)}/ - block.call(restore(value)) - end + block.call(restore(value)) } end # just like Hash#has_key? def has_key?(key) - return @registry.has_key?(@prefix + key) + return @registry.has_key?(key) end alias include? has_key? alias member? has_key? # just like Hash#has_both? def has_both?(key, value) - return @registry.has_both?(@prefix + key, store(value)) + return @registry.has_both?(key, store(value)) end # just like Hash#has_value? @@ -205,7 +216,7 @@ module Irc # just like Hash#index? def index(value) ind = @registry.index(store(value)) - if ind && ind.gsub!(/^#{Regexp.escape(@prefix)}/, "") + if ind return ind else return nil @@ -214,27 +225,19 @@ module Irc # delete a key from the registry def delete(key) - return @registry.delete(@prefix + key) + return @registry.delete(key) end # returns a list of your keys def keys - return @registry.keys.collect {|key| - if key.gsub!(/^#{Regexp.escape(@prefix)}/, "") - key - else - nil - end - }.compact + return @registry.keys end # Return an array of all associations [key, value] in your namespace def to_a ret = Array.new @registry.each {|key, value| - if key.gsub!(/^#{Regexp.escape(@prefix)}/, "") - ret << [key, restore(value)] - end + ret << [key, restore(value)] } return ret end @@ -243,20 +246,14 @@ module Irc def to_hash ret = Hash.new @registry.each {|key, value| - if key.gsub!(/^#{Regexp.escape(@prefix)}/, "") - ret[key] = restore(value) - end + ret[key] = restore(value) } return ret end # empties the registry (restricted to your namespace) def clear - @registry.each_key {|key| - if key =~ /^#{Regexp.escape(@prefix)}/ - @registry.delete(key) - end - } + @registry.clear end alias truncate clear |