From 597fbb963c7a204d677ec8e526223290ce45e03d Mon Sep 17 00:00:00 2001 From: Justin Balthrop Date: Thu, 19 Nov 2009 15:45:53 -0800 Subject: [PATCH] refactor and add PartitionedDatabase --- bdb.gemspec | 3 ++ lib/bdb/database.rb | 97 ++++----------------------------------------- 2 files changed, 10 insertions(+), 90 deletions(-) diff --git a/bdb.gemspec b/bdb.gemspec index 3faa693..bad9ac5 100644 --- a/bdb.gemspec +++ b/bdb.gemspec @@ -22,8 +22,11 @@ Gem::Specification.new do |s| "ext/bdb.c", "ext/bdb.h", "ext/extconf.rb", + "lib/bdb/base.rb", "lib/bdb/database.rb", "lib/bdb/environment.rb", + "lib/bdb/partitioned_database.rb", + "lib/bdb/result_set.rb", "test/benchmark.rb", "test/cursor_test.rb", "test/db_test.rb", diff --git a/lib/bdb/database.rb b/lib/bdb/database.rb index e907a05..10434b5 100644 --- a/lib/bdb/database.rb +++ b/lib/bdb/database.rb @@ -1,23 +1,11 @@ -require 'bdb' -require 'tuple' -require File.dirname(__FILE__) + '/environment' +require 'bdb/base' -class Bdb::Database +class Bdb::Database < Bdb::Base def initialize(name, opts = {}) - @name = name - @config = Bdb::Environment.config.merge(opts) - @indexes = {} - end - attr_reader :name, :indexes - - def config(config = {}) - @config.merge!(config) - end - - def index_by(field, opts = {}) - raise "index on #{field} already exists" if indexes[field] - indexes[field] = opts + @name = name + super(opts) end + attr_reader :name def db(index = nil) if @db.nil? @@ -70,7 +58,7 @@ class Bdb::Database def get(*keys, &block) opts = keys.last.kind_of?(Hash) ? keys.pop : {} db = db(opts[:field]) - set = ResultSet.new(opts, &block) + set = Bdb::ResultSet.new(opts, &block) flags = opts[:modify] ? Bdb::DB_RMW : 0 flags = 0 if environment.disable_transactions? @@ -139,7 +127,7 @@ class Bdb::Database end end set.results - rescue ResultSet::LimitReached + rescue Bdb::ResultSet::LimitReached set.results end @@ -166,22 +154,6 @@ class Bdb::Database end end - def environment - @environment ||= Bdb::Environment.new(config[:path], self) - end - - def transaction(nested = true, &block) - environment.transaction(nested, &block) - end - - def synchronize(&block) - environment.synchronize(&block) - end - - def checkpoint(opts = {}) - environment.synchronize(opts) - end - private def get_key(key, opts) @@ -209,59 +181,4 @@ private end end end - - class ResultSet - class LimitReached < Exception; end - - def initialize(opts, &block) - @block = block - @count = 0 - @limit = opts[:limit] || opts[:per_page] - @limit = @limit.to_i if @limit - @offset = opts[:offset] || (opts[:page] ? @limit * (opts[:page] - 1) : 0) - @offset = @offset.to_i if @offset - - if @group = opts[:group] - raise 'block not supported with group' if @block - @results = {} - else - @results = [] - end - end - attr_reader :count, :group, :limit, :offset, :results - - def <<(item) - @count += 1 - return if count <= offset - - raise LimitReached if limit and count > limit + offset - - if group - key = item.bdb_locator_key - group_key = group.is_a?(Fixnum) ? key[0,group] : key - (results[group_key] ||= []) << item - elsif @block - @block.call(item) - else - results << item - end - end - end -end - -class Object - attr_accessor :bdb_locator_key -end - -# Array comparison should try Tuple comparison first. -class Array - cmp = instance_method(:<=>) - - define_method(:<=>) do |other| - begin - Tuple.dump(self) <=> Tuple.dump(other) - rescue TypeError => e - cmp.bind(self).call(other) - end - end end