ccp 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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