Skip to content

Commit d24560e

Browse files
committed
AtomicFixnum methods #increment and #decrement now support optional delta
1 parent 6e4a93d commit d24560e

File tree

7 files changed

+74
-20
lines changed

7 files changed

+74
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### Upcoming Release v0.9.1 (TBD)
2+
3+
* `AtomicFixnum` methods `#increment` and `#decrement` now support optional delta
4+
15
## Current Release v0.9.0 (10 July 2015)
26

37
* Updated `AtomicReference`

ext/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,23 @@ public IRubyObject increment() {
6666
return getRuntime().newFixnum(atomicLong.incrementAndGet());
6767
}
6868

69+
@JRubyMethod(name = {"increment", "up"})
70+
public IRubyObject increment(IRubyObject value) {
71+
long delta = rubyFixnumToLong(value);
72+
return getRuntime().newFixnum(atomicLong.addAndGet(delta));
73+
}
74+
6975
@JRubyMethod(name = {"decrement", "down"})
7076
public IRubyObject decrement() {
7177
return getRuntime().newFixnum(atomicLong.decrementAndGet());
7278
}
7379

80+
@JRubyMethod(name = {"decrement", "down"})
81+
public IRubyObject decrement(IRubyObject value) {
82+
long delta = rubyFixnumToLong(value);
83+
return getRuntime().newFixnum(atomicLong.addAndGet(-delta));
84+
}
85+
7486
@JRubyMethod(name = "compare_and_set")
7587
public IRubyObject compareAndSet(ThreadContext context, IRubyObject expect, IRubyObject update) {
7688
return getRuntime().newBoolean(atomicLong.compareAndSet(rubyFixnumToLong(expect), rubyFixnumToLong(update)));

ext/concurrent/atomic_fixnum.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,26 @@ VALUE method_atomic_fixnum_value_set(VALUE self, VALUE value) {
3333
return(value);
3434
}
3535

36-
VALUE method_atomic_fixnum_increment(VALUE self) {
36+
VALUE method_atomic_fixnum_increment(int argc, VALUE* argv, VALUE self) {
3737
long long value = NUM2LL((VALUE) DATA_PTR(self));
38-
return method_atomic_fixnum_value_set(self, LL2NUM(value + 1));
38+
long long delta = 1;
39+
rb_check_arity(argc, 0, 1);
40+
if (argc == 1) {
41+
Check_Type(argv[0], T_FIXNUM);
42+
delta = NUM2LL(argv[0]);
43+
}
44+
return method_atomic_fixnum_value_set(self, LL2NUM(value + delta));
3945
}
4046

41-
VALUE method_atomic_fixnum_decrement(VALUE self) {
47+
VALUE method_atomic_fixnum_decrement(int argc, VALUE* argv, VALUE self) {
4248
long long value = NUM2LL((VALUE) DATA_PTR(self));
43-
return method_atomic_fixnum_value_set(self, LL2NUM(value - 1));
49+
long long delta = 1;
50+
rb_check_arity(argc, 0, 1);
51+
if (argc == 1) {
52+
Check_Type(argv[0], T_FIXNUM);
53+
delta = NUM2LL(argv[0]);
54+
}
55+
return method_atomic_fixnum_value_set(self, LL2NUM(value - delta));
4456
}
4557

4658
VALUE method_atomic_fixnum_compare_and_set(VALUE self, VALUE rb_expect, VALUE rb_update) {

ext/concurrent/atomic_fixnum.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ VALUE atomic_fixnum_allocate(VALUE);
66
VALUE method_atomic_fixnum_initialize(int, VALUE*, VALUE);
77
VALUE method_atomic_fixnum_value(VALUE);
88
VALUE method_atomic_fixnum_value_set(VALUE, VALUE);
9-
VALUE method_atomic_fixnum_increment(VALUE);
10-
VALUE method_atomic_fixnum_decrement(VALUE);
9+
VALUE method_atomic_fixnum_increment(int, VALUE*, VALUE);
10+
VALUE method_atomic_fixnum_decrement(int, VALUE*, VALUE);
1111
VALUE method_atomic_fixnum_compare_and_set(VALUE, VALUE, VALUE);
1212

1313
#endif

ext/concurrent/rb_concurrent.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ void Init_extension() {
4949
rb_define_method(rb_cAtomicFixnum, "initialize", method_atomic_fixnum_initialize, -1);
5050
rb_define_method(rb_cAtomicFixnum, "value", method_atomic_fixnum_value, 0);
5151
rb_define_method(rb_cAtomicFixnum, "value=", method_atomic_fixnum_value_set, 1);
52-
rb_define_method(rb_cAtomicFixnum, "increment", method_atomic_fixnum_increment, 0);
53-
rb_define_method(rb_cAtomicFixnum, "decrement", method_atomic_fixnum_decrement, 0);
52+
rb_define_method(rb_cAtomicFixnum, "increment", method_atomic_fixnum_increment, -1);
53+
rb_define_method(rb_cAtomicFixnum, "decrement", method_atomic_fixnum_decrement, -1);
5454
rb_define_method(rb_cAtomicFixnum, "compare_and_set", method_atomic_fixnum_compare_and_set, 2);
5555
rb_define_alias(rb_cAtomicFixnum, "up", "increment");
5656
rb_define_alias(rb_cAtomicFixnum, "down", "decrement");

lib/concurrent/atomic/atomic_fixnum.rb

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,26 @@ def value=(value)
6666

6767
# @!macro [attach] atomic_fixnum_method_increment
6868
#
69-
# Increases the current value by 1.
69+
# Increases the current value by the given amount (defaults to 1).
70+
#
71+
# @param [Fixnum] delta the amount by which to increase the current value
7072
#
7173
# @return [Fixnum] the current value after incrementation
72-
def increment
73-
synchronize { ns_set(@value + 1) }
74+
def increment(delta = 1)
75+
synchronize { ns_set(@value + delta.to_i) }
7476
end
7577

7678
alias_method :up, :increment
7779

7880
# @!macro [attach] atomic_fixnum_method_decrement
7981
#
80-
# Decreases the current value by 1.
82+
# Decreases the current value by the given amount (defaults to 1).
83+
#
84+
# @param [Fixnum] delta the amount by which to decrease the current value
8185
#
8286
# @return [Fixnum] the current value after decrementation
83-
def decrement
84-
synchronize { ns_set(@value - 1) }
87+
def decrement(delta = 1)
88+
synchronize { ns_set(@value - delta.to_i) }
8589
end
8690

8791
alias_method :down, :decrement
@@ -97,8 +101,8 @@ def decrement
97101
# @return [Fixnum] true if the value was updated else false
98102
def compare_and_set(expect, update)
99103
synchronize do
100-
if @value == expect
101-
@value = update
104+
if @value == expect.to_i
105+
@value = update.to_i
102106
true
103107
else
104108
false

spec/concurrent/atomic/atomic_fixnum_spec.rb

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,35 +52,57 @@
5252

5353
context '#increment' do
5454

55-
it 'increases the value by one' do
55+
it 'increases the value by one when no argument is given' do
5656
counter = described_class.new(10)
5757
3.times{ counter.increment }
5858
expect(counter.value).to eq 13
5959
end
6060

61-
it 'returns the new value' do
61+
it 'returns the new value when no argument is given' do
6262
counter = described_class.new(10)
6363
expect(counter.increment).to eq 11
6464
end
6565

66+
it 'increases the value by the given argument' do
67+
counter = described_class.new(10)
68+
counter.increment(5)
69+
expect(counter.value).to eq 15
70+
end
71+
72+
it 'returns the new value the given argument' do
73+
counter = described_class.new(10)
74+
expect(counter.increment(5)).to eq 15
75+
end
76+
6677
it 'is aliased as #up' do
6778
expect(described_class.new(10).up).to eq 11
6879
end
6980
end
7081

7182
context '#decrement' do
7283

73-
it 'decreases the value by one' do
84+
it 'decreases the value by one when no argument is given' do
7485
counter = described_class.new(10)
7586
3.times{ counter.decrement }
7687
expect(counter.value).to eq 7
7788
end
7889

79-
it 'returns the new value' do
90+
it 'returns the new value when no argument is given' do
8091
counter = described_class.new(10)
8192
expect(counter.decrement).to eq 9
8293
end
8394

95+
it 'decreases the value by the given argument' do
96+
counter = described_class.new(10)
97+
counter.decrement(5)
98+
expect(counter.value).to eq 5
99+
end
100+
101+
it 'returns the new value the given argument' do
102+
counter = described_class.new(10)
103+
expect(counter.decrement(5)).to eq 5
104+
end
105+
84106
it 'is aliased as #down' do
85107
expect(described_class.new(10).down).to eq 9
86108
end

0 commit comments

Comments
 (0)