about summary refs log tree commit
path: root/lib/metropolis/tc/hdb.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-11-23 19:45:52 -0800
committerEric Wong <normalperson@yhbt.net>2010-11-23 19:45:52 -0800
commit61120b1268679bb8ffa157736e91e6846fd2a372 (patch)
tree26ca738b3208164e7438599b7f25b3248cf76db8 /lib/metropolis/tc/hdb.rb
parent0f3c1c14630fda58363ffd7d3a942041ca2419eb (diff)
downloadmetropolis-61120b1268679bb8ffa157736e91e6846fd2a372.tar.gz
tc/hdb: add exclusive mode, lock disabling
The :exclusive mode behaves like TokyoTyrant and keeps the
database opened in read-write mode, preventing other processes
from accessing the database.  This will be useful on Rubies
without a GVL.

:readonly no longer disables locking by default
instead "rdlock=false" must be passed in the query
parameter.  Write locks may also be disabled with
the "wrlock=false" query parameter.
Diffstat (limited to 'lib/metropolis/tc/hdb.rb')
-rw-r--r--lib/metropolis/tc/hdb.rb27
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/metropolis/tc/hdb.rb b/lib/metropolis/tc/hdb.rb
index ebd7a17..ce6d13a 100644
--- a/lib/metropolis/tc/hdb.rb
+++ b/lib/metropolis/tc/hdb.rb
@@ -4,6 +4,7 @@
 # local machine so there is never anything that needs yielding to threads.
 module Metropolis::TC::HDB
   autoload :RO, 'metropolis/tc/hdb/ro'
+  autoload :EX, 'metropolis/tc/hdb/ex'
 
   TCHDB = TokyoCabinet::HDB # :nodoc
   include Metropolis::Common
@@ -13,13 +14,34 @@ module Metropolis::TC::HDB
     path_pattern = opts[:path_pattern]
     path_pattern.scan(/%\d*x/).size == 1 or
       raise ArgumentError, "only one '/%\d*x/' may appear in #{path_pattern}"
+
+    @rd_flags = TCHDB::OREADER
+    @wr_flags = TCHDB::OWRITER
+
     @optimize = nil
     if query = opts[:query]
+      case query['rdlock']
+      when 'true', nil
+      when 'false'
+        @rd_flags |= TCHDB::ONOLCK
+      else
+        raise ArgumentError, "'rdlock' must be 'true' or 'false'"
+      end
+
+      case query['wrlock']
+      when 'true', nil
+      when 'false'
+        @wr_flags |= TCHDB::ONOLCK
+      else
+        raise ArgumentError, "'wrlock' must be 'true' or 'false'"
+      end
+
       flags = 0
       @optimize = %w(bnum apow fpow).map do |x|
         v = query[x]
         v ? v.to_i : nil
       end
+
       case large = query['large']
       when 'false', nil
       when 'true'
@@ -27,6 +49,7 @@ module Metropolis::TC::HDB
       else
         raise ArgumentError, "invalid 'large' value: #{large}"
       end
+
       case compress = query['compress']
       when nil
       when 'deflate', 'bzip', 'tcbs'
@@ -48,12 +71,10 @@ module Metropolis::TC::HDB
       end
       [ hdb, path ]
     end
-    @rd_flags = TCHDB::OREADER
-    @wr_flags = TCHDB::OWRITER
     extend(RO) if @readonly
+    extend(EX) if @exclusive
   end
 
-
   def ex!(msg, hdb)
     raise "#{msg}: #{hdb.errmsg(hdb.ecode)}"
   end