Class: Bdb::Environment

Inherits:
Object show all
Includes:
Replication
Defined in:
lib/bdb/environment.rb

Constant Summary collapse

@@env =
{}

Constants included from Replication

Replication::ACK_POLICY, Replication::DEFAULT_PORT, Replication::NUM_THREADS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Replication

#master?, #replicate, #replicate?

Constructor Details

#initialize(path) ⇒ Environment

Returns a new instance of Environment.



14
15
16
# File 'lib/bdb/environment.rb', line 14

def initialize(path)
  @path = path
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



17
18
19
# File 'lib/bdb/environment.rb', line 17

def path
  @path
end

Class Method Details

.[](path) ⇒ Object



19
20
21
# File 'lib/bdb/environment.rb', line 19

def self.[](path)
  new(path)
end

.config(config = {}) ⇒ Object



23
24
25
26
27
28
29
30
31
# File 'lib/bdb/environment.rb', line 23

def self.config(config = {})
  @config ||= {
    :max_locks    => 5000,
    :lock_timeout => 30 * 1000 * 1000,
    :txn_timeout  => 30 * 1000 * 1000,
    :cache_size   => 1  * 1024 * 1024,
  }
  @config.merge!(config)
end

.new(path, database = nil) ⇒ Object



6
7
8
9
10
11
12
# File 'lib/bdb/environment.rb', line 6

def self.new(path, database = nil)
  # Only allow one environment per path.
  path = File.expand_path(path)
  @@env[path] ||= super(path)
  @@env[path].databases << database if database
  @@env[path]
end

.replicate(path, opts) ⇒ Object



39
40
41
# File 'lib/bdb/environment.rb', line 39

def self.replicate(path, opts)
  self[path].replicate(opts)
end

Instance Method Details

#checkpoint(opts = {}) ⇒ Object



103
104
105
106
# File 'lib/bdb/environment.rb', line 103

def checkpoint(opts = {})
  return if disable_transactions?
  env.txn_checkpoint(opts[:kbyte] || 0, opts[:min] || 0, opts[:force] ? Bdb::DB_FORCE : 0)
end

#closeObject



75
76
77
78
79
80
81
82
# File 'lib/bdb/environment.rb', line 75

def close
  return unless @env
  synchronize do
    databases.each {|database| database.close}
    @env.close
    @env = nil
  end
end

#config(config = {}) ⇒ Object



33
34
35
36
# File 'lib/bdb/environment.rb', line 33

def config(config = {})
  @config ||= self.class.config
  @config.merge!(config)
end

#databasesObject



43
44
45
# File 'lib/bdb/environment.rb', line 43

def databases
  @databases ||= []
end

#disable_transactions?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/bdb/environment.rb', line 108

def disable_transactions?
  config[:disable_transactions]
end

#envObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/bdb/environment.rb', line 47

def env
  if @env.nil?
    synchronize do
      @env = Bdb::Env.new(0)
      if disable_transactions?
        env_flags = Bdb::DB_CREATE | Bdb::DB_INIT_MPOOL
      else
        env_flags = Bdb::DB_CREATE | Bdb::DB_INIT_TXN | Bdb::DB_INIT_LOCK |
                    Bdb::DB_REGISTER | Bdb::DB_RECOVER | Bdb::DB_INIT_MPOOL | Bdb::DB_THREAD

        env_flags |= Bdb::DB_INIT_REP if replicate?
      end
      @env.cachesize = config[:cache_size] if config[:cache_size]
      @env.set_timeout(config[:txn_timeout],  Bdb::DB_SET_TXN_TIMEOUT)  if config[:txn_timeout]
      @env.set_timeout(config[:lock_timeout], Bdb::DB_SET_LOCK_TIMEOUT) if config[:lock_timeout]
      @env.set_lk_max_locks(config[:max_locks]) if config[:max_locks]
      @env.set_lk_detect(Bdb::DB_LOCK_RANDOM)
      @env.flags_on = Bdb::DB_TXN_WRITE_NOSYNC | Bdb::DB_TIME_NOTGRANTED
      init_replication(@env) if replicate?

      @env.open(path, env_flags, 0)
      start_replication(@env) if replicate?
      @exit_handler ||= at_exit { close }
    end
  end
  @env
end

#synchronizeObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/bdb/environment.rb', line 112

def synchronize
  @mutex ||= Mutex.new
  if @thread_id == thread_id
    yield
  else
    @mutex.synchronize do
      begin
        @thread_id = thread_id
        Thread.exclusive { yield }
      ensure
        @thread_id = nil
      end
    end
  end
rescue Bdb::DbError => e
  exit!(9) if e.code == Bdb::DB_RUNRECOVERY    
  retry if transaction.nil? and e.code == Bdb::DB_LOCK_DEADLOCK
  raise e
end

#thread_idObject



132
133
134
# File 'lib/bdb/environment.rb', line 132

def thread_id
  Thread.current.object_id
end

#transaction(nested = true) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/bdb/environment.rb', line 84

def transaction(nested = true)
  return @transaction unless block_given?
  return yield if disable_transactions?

  synchronize do
    parent = @transaction
    begin
      @transaction = env.txn_begin(nested ? parent : nil, 0)
      value = yield
      @transaction.commit(0)
      @transaction = nil
      value
    ensure
      @transaction.abort if @transaction
      @transaction = parent
    end
  end
end