thread_safe 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca3399bd6ea44fe01680773e7b50bd0e7ba83180
4
- data.tar.gz: 5538a41397738daa6a068386fb75c957b68554f9
3
+ metadata.gz: becd0122b50b5237811fa86271f7d33724680011
4
+ data.tar.gz: 3111e146b92de7b07e7b052b3dd126aaad1aca2c
5
5
  SHA512:
6
- metadata.gz: 4de26c2ec5e34448f165a1e7eb6893025d969c41be6f5bbbe02e158c31151871de7c71d9cf5ee8f9d7effc48c871a74b178c030fede73061a6f9c9273a220f9c
7
- data.tar.gz: 2f0bddce90244d49e4d0443ffe9d739f8f1732021875e5707c9224add8aac54cce31472accb0fc8471273c12c755cc56e797f5b0087160ba203e8caf3f72387c
6
+ metadata.gz: ae11d6069603a1f4a6ae9ce62347629b22b2841c4008f248fd05b5c5fc2449913fbc0554919f4615e0abd55fdb903a42eee1520fbc723e17618e7b6419933559
7
+ data.tar.gz: 8c80390a923556d2627d89af464e51ddae6ac9b5c44a485c6c6c0ad804b01aeed631680a7ab23c63e46293d8649978eceb5dd40cc6218d1f101597baf50b6ee1
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ test/version_tmp
19
19
  tmp
20
20
  .DS_Store
21
21
  *.swp
22
+ test/package.jar
data/README.md CHANGED
@@ -28,14 +28,22 @@ sh = ThreadSafe::Hash.new # supports standard Hash.new forms
28
28
  ```
29
29
 
30
30
  `ThreadSafe::Cache` also exists, as a hash-like object, and should have
31
- much better performance characteristics under concurrency than
31
+ much better performance characteristics esp. under high concurrency than
32
32
  `ThreadSafe::Hash`. However, `ThreadSafe::Cache` is not strictly semantically
33
- equivalent to ruby Hash -- for instance, it does not neccesarily ordered by
34
- insertion time as Hash is. For most uses it should do fine though, and we
35
- recommend you consider `ThreadSafe::Cache` instead of `ThreadSafe::Hash` for your
36
- concurrency-safe hash needs.
33
+ equivalent to a ruby `Hash` -- for instance, it does not necessarily retain
34
+ ordering by insertion time as `Hash` does. For most uses it should do fine
35
+ though, and we recommend you consider `ThreadSafe::Cache` instead of
36
+ `ThreadSafe::Hash` for your concurrency-safe hash needs. It understands some
37
+ options when created (depending on your ruby platform) that control some of the
38
+ internals - when unsure just leave them out:
37
39
 
38
40
 
41
+ ```ruby
42
+ require 'thread_safe'
43
+
44
+ cache = ThreadSafe::Cache.new
45
+ ```
46
+
39
47
  ## Contributing
40
48
 
41
49
  1. Fork it
@@ -178,11 +178,17 @@ public class JRubyCacheBackendLibrary implements Library {
178
178
  return getRuntime().newBoolean(map.replace(key, oldValue, newValue));
179
179
  }
180
180
 
181
- @JRubyMethod(name = {"key?"}, required = 1)
181
+ @JRubyMethod(name = "key?", required = 1)
182
182
  public RubyBoolean has_key_p(IRubyObject key) {
183
183
  return map.containsKey(key) ? getRuntime().getTrue() : getRuntime().getFalse();
184
184
  }
185
185
 
186
+ @JRubyMethod
187
+ public IRubyObject key(IRubyObject value) {
188
+ final IRubyObject key = map.findKey(value);
189
+ return key == null ? getRuntime().getNil() : key;
190
+ }
191
+
186
192
  @JRubyMethod
187
193
  public IRubyObject replace_if_exists(IRubyObject key, IRubyObject value) {
188
194
  IRubyObject result = map.replace(key, value);
@@ -25,4 +25,7 @@ public interface ConcurrentHashMap<K, V> {
25
25
  public Set<Map.Entry<K,V>> entrySet();
26
26
  public int size();
27
27
  public V getValueOrDefault(Object key, V defaultValue);
28
+
29
+ public boolean containsValue(V value);
30
+ public K findKey(V value);
28
31
  }
@@ -2430,8 +2430,8 @@ public class ConcurrentHashMapV8<K, V>
2430
2430
  @SuppressWarnings("serial") static class Traverser<K,V,R> {
2431
2431
  final ConcurrentHashMapV8<K, V> map;
2432
2432
  Node next; // the next entry to use
2433
- Object nextKey; // cached key field of next
2434
- Object nextVal; // cached val field of next
2433
+ K nextKey; // cached key field of next
2434
+ V nextVal; // cached val field of next
2435
2435
  Node[] tab; // current table; updated if resized
2436
2436
  int index; // index of bin to use next
2437
2437
  int baseIndex; // current index of initial table
@@ -2461,9 +2461,9 @@ public class ConcurrentHashMapV8<K, V>
2461
2461
  * Advances next; returns nextVal or null if terminated.
2462
2462
  * See above for explanation.
2463
2463
  */
2464
- final Object advance() {
2464
+ final V advance() {
2465
2465
  Node e = next;
2466
- Object ev = null;
2466
+ V ev = null;
2467
2467
  outer: do {
2468
2468
  if (e != null) // advance past used/skipped node
2469
2469
  e = e.next;
@@ -2489,8 +2489,8 @@ public class ConcurrentHashMapV8<K, V>
2489
2489
  } // visit upper slots if present
2490
2490
  index = (i += baseSize) < n ? i : (baseIndex = b + 1);
2491
2491
  }
2492
- nextKey = e.key;
2493
- } while ((ev = e.val) == null); // skip deleted or special nodes
2492
+ nextKey = (K) e.key;
2493
+ } while ((ev = (V) e.val) == null); // skip deleted or special nodes
2494
2494
  next = e;
2495
2495
  return nextVal = ev;
2496
2496
  }
@@ -2730,6 +2730,18 @@ public class ConcurrentHashMapV8<K, V>
2730
2730
  return false;
2731
2731
  }
2732
2732
 
2733
+ public K findKey(Object value) {
2734
+ if (value == null)
2735
+ throw new NullPointerException();
2736
+ Object v;
2737
+ Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2738
+ while ((v = it.advance()) != null) {
2739
+ if (v == value || value.equals(v))
2740
+ return it.nextKey;
2741
+ }
2742
+ return null;
2743
+ }
2744
+
2733
2745
  /**
2734
2746
  * Legacy method testing if some key maps into the specified value
2735
2747
  * in this table. This method is identical in functionality to
@@ -2422,8 +2422,8 @@ public class ConcurrentHashMapV8<K, V>
2422
2422
  @SuppressWarnings("serial") static class Traverser<K,V,R> {
2423
2423
  final ConcurrentHashMapV8<K, V> map;
2424
2424
  Node next; // the next entry to use
2425
- Object nextKey; // cached key field of next
2426
- Object nextVal; // cached val field of next
2425
+ K nextKey; // cached key field of next
2426
+ V nextVal; // cached val field of next
2427
2427
  AtomicReferenceArray<Node> tab; // current table; updated if resized
2428
2428
  int index; // index of bin to use next
2429
2429
  int baseIndex; // current index of initial table
@@ -2453,9 +2453,9 @@ public class ConcurrentHashMapV8<K, V>
2453
2453
  * Advances next; returns nextVal or null if terminated.
2454
2454
  * See above for explanation.
2455
2455
  */
2456
- final Object advance() {
2456
+ final V advance() {
2457
2457
  Node e = next;
2458
- Object ev = null;
2458
+ V ev = null;
2459
2459
  outer: do {
2460
2460
  if (e != null) // advance past used/skipped node
2461
2461
  e = e.next;
@@ -2481,8 +2481,8 @@ public class ConcurrentHashMapV8<K, V>
2481
2481
  } // visit upper slots if present
2482
2482
  index = (i += baseSize) < n ? i : (baseIndex = b + 1);
2483
2483
  }
2484
- nextKey = e.key;
2485
- } while ((ev = e.val) == null); // skip deleted or special nodes
2484
+ nextKey = (K) e.key;
2485
+ } while ((ev = (V) e.val) == null); // skip deleted or special nodes
2486
2486
  next = e;
2487
2487
  return nextVal = ev;
2488
2488
  }
@@ -2722,6 +2722,18 @@ public class ConcurrentHashMapV8<K, V>
2722
2722
  return false;
2723
2723
  }
2724
2724
 
2725
+ public K findKey(Object value) {
2726
+ if (value == null)
2727
+ throw new NullPointerException();
2728
+ Object v;
2729
+ Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2730
+ while ((v = it.advance()) != null) {
2731
+ if (v == value || value.equals(v))
2732
+ return it.nextKey;
2733
+ }
2734
+ return null;
2735
+ }
2736
+
2725
2737
  /**
2726
2738
  * Legacy method testing if some key maps into the specified value
2727
2739
  * in this table. This method is identical in functionality to
@@ -95,6 +95,12 @@ module ThreadSafe
95
95
  each_pair {|k, v| yield v}
96
96
  end unless method_defined?(:each_value)
97
97
 
98
+ def key(value)
99
+ each_pair {|k, v| return k if v == value}
100
+ nil
101
+ end unless method_defined?(:key)
102
+ alias_method :index, :key if RUBY_VERSION < '1.9'
103
+
98
104
  def empty?
99
105
  each_pair {|k, v| return false}
100
106
  true
@@ -1,3 +1,21 @@
1
+ module ThreadSafe
2
+ VERSION = "0.3.1"
3
+ end
4
+
5
+ # NOTE: <= 0.2.0 used Threadsafe::VERSION
6
+ # @private
1
7
  module Threadsafe
2
- VERSION = "0.2.0"
8
+
9
+ # @private
10
+ def self.const_missing(name)
11
+ name = name.to_sym
12
+ if ThreadSafe.const_defined?(name)
13
+ warn "[DEPRECATION] `Threadsafe::#{name}' is deprecated, use `ThreadSafe::#{name}' instead."
14
+ ThreadSafe.const_get(name)
15
+ else
16
+ warn "[DEPRECATION] the `Threadsafe' module is deprecated, please use `ThreadSafe` instead."
17
+ super
18
+ end
19
+ end
20
+
3
21
  end
data/test/test_cache.rb CHANGED
@@ -371,6 +371,16 @@ class TestCache < Test::Unit::TestCase
371
371
  end
372
372
 
373
373
  def test_key
374
+ with_or_without_default_proc do
375
+ assert_equal nil, @cache.key(1)
376
+ @cache[:a] = 1
377
+ assert_equal :a, @cache.key(1)
378
+ assert_equal nil, @cache.key(0)
379
+ assert_equal :a, @cache.index(1) if RUBY_VERSION =~ /1\.8/
380
+ end
381
+ end
382
+
383
+ def test_key?
374
384
  with_or_without_default_proc do
375
385
  assert_equal false, @cache.key?(:a)
376
386
  @cache[:a] = 1
@@ -378,7 +388,7 @@ class TestCache < Test::Unit::TestCase
378
388
  end
379
389
  end
380
390
 
381
- def test_value
391
+ def test_value?
382
392
  with_or_without_default_proc do
383
393
  assert_equal false, @cache.value?(1)
384
394
  @cache[:a] = 1
data/thread_safe.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
17
  gem.name = "thread_safe"
18
18
  gem.require_paths = ["lib"]
19
- gem.version = Threadsafe::VERSION
19
+ gem.version = ThreadSafe::VERSION
20
20
  gem.license = "Apache-2.0"
21
21
 
22
22
  gem.add_dependency 'atomic', ['>= 1.1.7', '< 2']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thread_safe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Oliver Nutter
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-26 00:00:00.000000000 Z
12
+ date: 2014-03-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: atomic
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.2.0
118
+ rubygems_version: 2.2.2
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: A collection of data structures and utilities to make thread-safe programming
@@ -128,4 +128,3 @@ test_files:
128
128
  - test/test_hash.rb
129
129
  - test/test_helper.rb
130
130
  - test/test_synchronized_delegator.rb
131
- has_rdoc: