ccp 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  .bundle
3
+ .ruby-version
3
4
  Gemfile.lock
4
5
  pkg/*
5
6
  tmp/*
@@ -5,7 +5,6 @@ module Ccp
5
5
  def set(k,v) ; raise NotImplementedError, "subclass resposibility"; end
6
6
  def del(k) ; raise NotImplementedError, "subclass resposibility"; end
7
7
  def keys ; raise NotImplementedError, "subclass resposibility"; end
8
- def read! ; keys.inject({}){|h,k| h[k] = get(k); h } ; end
9
8
  def exist?(k); !! get(k) ; end
10
9
  def key?(k) ; exist?(k) ; end
11
10
 
@@ -32,6 +31,16 @@ module Ccp
32
31
  def self.open(*args); new.tap{|kvs| kvs.open(*args)}; end
33
32
  end
34
33
  end
34
+
35
+ # bulk operation
36
+ def read ; keys.inject({}){|h,k| h[k] = get(k); h } ; end
37
+ def write(h) ; h.each_pair{|k,v| set(k,v)} ; end
38
+
39
+ # backward compat (until 0.3.6)
40
+ def read!
41
+ STDERR.puts "DEPRECATION WARNING: #{self.class}#read! will be removed in 0.3.6, use read instead"
42
+ read
43
+ end
35
44
  end
36
45
  end
37
46
  end
@@ -7,10 +7,11 @@ module Ccp
7
7
  def set(k,v) ; W{ super }; end
8
8
  def del(k) ; W{ super }; end
9
9
  def count ; R{ super }; end
10
- def read! ; R{ super }; end
11
10
  def keys ; R{ super }; end
12
11
  def first_key; R{ super }; end
13
12
  def first ; R{ super }; end
13
+ def read ; R{ super }; end
14
+ def write(h) ; W{ super }; end
14
15
  end
15
16
  end
16
17
  end
@@ -60,10 +60,10 @@ module Ccp
60
60
  ######################################################################
61
61
  ### bulk operations (not DRY but fast)
62
62
 
63
- def read!
64
- tryR("read!")
63
+ def read
64
+ tryR("read")
65
65
  hash = {}
66
- @db.iterinit or tokyo_error!("read!: ")
66
+ @db.iterinit or tokyo_error!("read: ")
67
67
  while k = @db.iternext
68
68
  v = @db.get(k) or tokyo_error!("get(%s): " % k)
69
69
  hash[k] = decode(v)
@@ -71,6 +71,15 @@ module Ccp
71
71
  return hash
72
72
  end
73
73
 
74
+ def write(h)
75
+ tryW("write")
76
+ h.each_pair do |k,v|
77
+ val = encode(v)
78
+ @db[k.to_s] = val or tokyo_error!("write(%s): " % k)
79
+ end
80
+ return h
81
+ end
82
+
74
83
  ######################################################################
75
84
  ### iterator
76
85
 
@@ -11,20 +11,20 @@ module Ccp
11
11
  READABLE = 2
12
12
  WRITABLE = 3
13
13
 
14
+ LOCKED_BY = proc{|c| Array(c).select{|i| i !~ %r{/ruby/[^/]+/gems/}}[0,5].join("\n") || c rescue c}
15
+
14
16
  def state
15
17
  @state || CLOSED
16
18
  end
17
19
 
18
20
  def locker_info
19
- pretty = proc{|c| Array(c).find{|i| i !~ %r{/ruby/[^/]+/gems/}} || c}
20
-
21
21
  if CONNECTIONS[@source]
22
- return pretty[CONNECTIONS[@source]]
22
+ return LOCKED_BY[CONNECTIONS[@source]]
23
23
  end
24
24
 
25
25
  target = File.basename(@source)
26
26
  CONNECTIONS.each_pair do |file, reason|
27
- return pretty[reason] if File.basename(file) == target
27
+ return LOCKED_BY[reason] if File.basename(file) == target
28
28
  end
29
29
 
30
30
  if CONNECTIONS.any?
@@ -34,67 +34,70 @@ module Ccp
34
34
  end
35
35
  end
36
36
 
37
- def open(mode)
37
+ def open(mode, locker = nil)
38
38
  Pathname(@source.to_s).parent.mkpath
39
39
 
40
40
  # open and mark filename for threading error
41
41
  if @db.open(@source.to_s, mode)
42
- CONNECTIONS[@db.path.to_s] = (caller rescue "???")
42
+ locker ||= (caller rescue "???")
43
+ STDERR.puts "LOCK: #{@source} by [#{LOCKED_BY[locker]}]" if @debug
44
+ CONNECTIONS[@db.path.to_s] = locker
43
45
  elsif threading_error?
44
- raise Tokyo::Locked, "%s is locked by %s" % [@source, locker_info]
46
+ raise Tokyo::Locked, "%s is locked by [%s]" % [@source, locker_info]
45
47
  else
46
48
  tokyo_error!("%s#open(%s,%s): " % [self.class, @source, mode])
47
49
  end
48
50
  end
49
51
 
50
- def __close__
52
+ def __close__(locker = nil)
51
53
  @db.close
52
54
  CONNECTIONS[@db.path] = nil
55
+ STDERR.puts "UNLOCK: #{@source} by [#{LOCKED_BY[locker || caller]}]" if @debug
53
56
  end
54
57
 
55
- def close
56
- C!
58
+ def close(locker = nil)
59
+ C!(locker)
57
60
  end
58
61
 
59
- def C!
62
+ def C!(locker = nil)
60
63
  case state
61
64
  when CLOSED ; # NOP
62
65
  when READABLE,
63
- WRITABLE ; __close__; @state = CLOSED
66
+ WRITABLE ; __close__(locker); @state = CLOSED
64
67
  else ; raise "unknown state: #{state}"
65
68
  end
66
69
  end
67
70
 
68
- def R!
71
+ def R!(locker = nil)
69
72
  case state
70
- when CLOSED ; open(HDB::OREADER); @state = READABLE
73
+ when CLOSED ; open(HDB::OREADER, locker); @state = READABLE
71
74
  when READABLE ; # NOP
72
75
  when WRITABLE ; # NOP
73
76
  else ; raise "unknown state: #{state}"
74
77
  end
75
78
  end
76
79
 
77
- def W!
80
+ def W!(locker = nil)
78
81
  case state
79
- when CLOSED ; open(HDB::OCREAT | HDB::OWRITER); @state = WRITABLE
80
- when READABLE ; C!; W!()
82
+ when CLOSED ; open(HDB::OCREAT | HDB::OWRITER, locker); @state = WRITABLE
83
+ when READABLE ; C!(locker); W!(locker)
81
84
  when WRITABLE ; # NOP
82
85
  else ; raise "unknown state: #{state}"
83
86
  end
84
87
  end
85
88
 
86
- def R(&block)
89
+ def R(locker = nil, &block)
87
90
  case state
88
- when CLOSED ; begin; R!(); yield; ensure; close; end
91
+ when CLOSED ; begin; R!(locker); yield; ensure; close(locker); end
89
92
  when READABLE ; yield
90
93
  when WRITABLE ; yield
91
94
  else ; raise "unknown state: #{state}"
92
95
  end
93
96
  end
94
97
 
95
- def W(&block)
98
+ def W(locker = nil, &block)
96
99
  case state
97
- when CLOSED ; begin; W!(); yield; ensure; close; end
100
+ when CLOSED ; begin; W!(locker); yield; ensure; close(locker); end
98
101
  when READABLE ; raise "reopen from read to write is not permitted"
99
102
  # TODO: close -> W -> close -> R ???
100
103
  when WRITABLE ; yield
@@ -2,7 +2,10 @@ module Ccp
2
2
  module Receivers
3
3
  module Skippable
4
4
  def execute(cmd)
5
- return false if skip?(cmd)
5
+ if skip?(cmd)
6
+ notify_skip(cmd)
7
+ return false
8
+ end
6
9
  super
7
10
  end
8
11
 
@@ -11,6 +14,11 @@ module Ccp
11
14
  key = "skip_%s" % cmd.class.name.underscore.gsub("/","_")
12
15
  data.set?(key)
13
16
  end
17
+
18
+ def notify_skip(cmd)
19
+ @logger ||= data.set?(:logger) ? data[:logger] : Logger.new(STDOUT)
20
+ @logger.debug Utils::Colorize.pink("[SKIP] #{cmd.class}")
21
+ end
14
22
  end
15
23
  end
16
24
  end
@@ -10,7 +10,7 @@ module Ccp
10
10
  end
11
11
 
12
12
  attr_reader :source, :kvs, :codec, :path
13
- delegate :get, :set, :del, :keys, :read!, :to=>"@kvs"
13
+ delegate :get, :set, :del, :keys, :read, :to=>"@kvs"
14
14
 
15
15
  def initialize(source, kvs, codec)
16
16
  @source = source
@@ -43,20 +43,33 @@ module Ccp
43
43
  )
44
44
  end
45
45
 
46
+ def close
47
+ @tables.each_pair do |_,kvs|
48
+ kvs.close
49
+ end
50
+ @tables = {}
51
+ end
52
+
46
53
  ######################################################################
47
54
  ### kvs
48
55
 
49
- def read!
56
+ def read
50
57
  if @path.directory?
51
58
  tables
52
59
  hash = {}
53
60
  @tables.each_pair do |k, kvs|
54
- hash[k] = kvs.read!
61
+ hash[k] = kvs.read
55
62
  end
56
63
  return hash
57
64
  else
58
- return @kvs.read!
65
+ return @kvs.read
59
66
  end
60
67
  end
68
+
69
+ # backward compat (until 0.3.6)
70
+ def read!
71
+ STDERR.puts "DEPRECATION WARNING: #{self.class}#read! will be removed in 0.3.6, use read instead"
72
+ read
73
+ end
61
74
  end
62
75
  end
@@ -1,3 +1,3 @@
1
1
  module Ccp
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  end
@@ -12,4 +12,6 @@ describe Ccp::Kvs::Core do
12
12
  it { should respond_to("touch") }
13
13
  it { should respond_to("exist?") }
14
14
  it { should respond_to("key?") }
15
+ it { should respond_to("read") }
16
+ it { should respond_to("write") }
15
17
  end
@@ -72,13 +72,23 @@ Ccp::Kvs.each do |klass|
72
72
  end
73
73
  end
74
74
 
75
- describe "#read!" do
75
+ describe "#read" do
76
76
  specify do
77
77
  kvs.touch
78
78
  kvs.codec! :json
79
79
  kvs.set(:a, 1)
80
80
  kvs.set(:b, ["x", 0])
81
- kvs.read!.should == {"a"=>1, "b"=>["x", 0]}
81
+ kvs.read.should == {"a"=>1, "b"=>["x", 0]}
82
+ end
83
+ end
84
+
85
+ describe "#write" do
86
+ specify do
87
+ kvs.touch
88
+ kvs.codec! :json
89
+ kvs.write("a"=>1, "b"=>["x", 0])
90
+ kvs["a"].should == 1
91
+ kvs["b"].should == ["x", 0]
82
92
  end
83
93
  end
84
94
 
@@ -206,15 +206,25 @@ describe Ccp::Kvs::Tokyo::Cabinet do
206
206
  end
207
207
 
208
208
  ######################################################################
209
- ### read!
209
+ ### read / write
210
210
 
211
- describe "#read!" do
211
+ describe "#read" do
212
212
  specify do
213
213
  put(:foo, 1)
214
214
  put(:bar, 2)
215
215
 
216
216
  kvs.R!
217
- kvs.read!.should == {"foo" => "1", "bar" => "2"}
217
+ kvs.read.should == {"foo" => "1", "bar" => "2"}
218
+ end
219
+ end
220
+
221
+ describe "#write" do
222
+ specify do
223
+ kvs.W!
224
+ kvs.write("foo" => "1", "bar" => "2")
225
+
226
+ kvs.get("foo").should == "1"
227
+ kvs.get("bar").should == "2"
218
228
  end
219
229
  end
220
230
 
@@ -37,7 +37,7 @@ describe Ccp::Storage do
37
37
  end
38
38
  end
39
39
 
40
- describe "#read!" do
40
+ describe "#read" do
41
41
  before { FileUtils.rm_rf(tmp_path) if tmp_path.directory? }
42
42
 
43
43
  context "(file)" do
@@ -50,7 +50,7 @@ describe Ccp::Storage do
50
50
  system("tchmgr put #{tch} b 0.1")
51
51
  }
52
52
  specify do
53
- subject.read!.should == {"a" => [1, 2], "b" => 0.1}
53
+ subject.read.should == {"a" => [1, 2], "b" => 0.1}
54
54
  end
55
55
  end
56
56
 
@@ -66,13 +66,21 @@ describe Ccp::Storage do
66
66
  system("tchmgr put #{tch}/b.json.tch y 0.1")
67
67
  }
68
68
  specify do
69
- subject.read!.should == {
69
+ subject.read.should == {
70
70
  "a" => {"x" => [1, 2], "y" => []},
71
71
  "b" => {"y" => 0.1},
72
72
  }
73
73
  end
74
74
  end
75
+ end
76
+
77
+ describe "#close" do
78
+ before { FileUtils.rm_rf(tmp_path) if tmp_path.directory? }
75
79
 
80
+ let(:tch) { tmp_path + "foo.json.tch" }
81
+ subject { Ccp::Storage.new(tch, Ccp::Kvs::Tch, Ccp::Serializers::Json) }
82
+
83
+ it { should respond_to(:close) }
76
84
  end
77
85
 
78
86
  # it { should respond_to(:tables) }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ccp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 4
10
- version: 0.3.4
9
+ - 5
10
+ version: 0.3.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - maiha
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-09-04 00:00:00 Z
18
+ date: 2013-10-29 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activesupport