Clover icon

Magnolia Module Memcached 5.4.2

  1. Project Clover database Wed Aug 19 2015 15:04:32 CEST
  2. Package info.magnolia.cache.concurrent

File StripedReadWriteLockSync.java

 

Coverage histogram

../../../../img/srcFileCovDistChart7.png
33% of files have more coverage

Code metrics

6
13
4
1
112
37
7
0.54
3.25
4
1.75
8% of code in this file is excluded from these metrics.

Classes

Class Line # Actions
StripedReadWriteLockSync 38 13 8% 7 7
0.695652269.6%
 

Contributing tests

This file is covered by 10 tests. .

Source view

1    /**
2    * Copyright Terracotta, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package info.magnolia.cache.concurrent;
17   
18    import java.util.Arrays;
19    import java.util.Collections;
20    import java.util.List;
21    import java.util.concurrent.locks.ReadWriteLock;
22   
23    /**
24    * Provides a number of Sync which allow fine-grained concurrency.
25    * Rather than locking a cache or a store,
26    * the individual elements or constituent objects can be locked. This dramatically increases
27    * the possible concurrency.
28    * <p/>
29    * The more stripes, the higher the concurrency. To be threadsafe, the instance of CacheLockProvider needs to be
30    * maintained for the entire life of the cache or store, so there is some added memory use.
31    * <p/>
32    * Though a new class, this code has been refactored from <code>BlockingCache</code>, where it has been in use
33    * in highly concurrent production environments for years.
34    * <p/>
35    * Based on the lock striping concept from Brian Goetz. See Java Concurrency in Practice 11.4.3
36    * @author Alex Snaps
37    */
 
38    public class StripedReadWriteLockSync {
39   
40    /**
41    * The default number of locks to use. Must be a power of 2.
42    * <p/>
43    * The choice of 2048 enables 2048 concurrent operations per cache or cache store, which should be enough for most
44    * uses.
45    */
46    public static final int DEFAULT_NUMBER_OF_MUTEXES = 2048;
47   
48    private final ReadWriteLockSync[] mutexes;
49    private final List<ReadWriteLockSync> mutexesAsList;
50    /**
51    * Constructs a striped mutex with the default 2048 stripes.
52    */
 
53  18 toggle public StripedReadWriteLockSync() {
54  18 this(DEFAULT_NUMBER_OF_MUTEXES);
55    }
56   
57    /**
58    * Constructs a striped mutex with the default 2048 stripes.
59    * <p/>
60    * The number of stripes determines the number of concurrent operations per cache or cache store.
61    * @param numberOfStripes - must be a factor of two
62    */
 
63  18 toggle public StripedReadWriteLockSync(int numberOfStripes) {
64  18 if ((numberOfStripes & (numberOfStripes - 1)) != 0) {
65  0 throw new IllegalArgumentException("Cannot create a CacheLockProvider with a non power-of-two number of stripes");
66    }
67  18 if (numberOfStripes == 0) {
68  0 throw new IllegalArgumentException("A zero size CacheLockProvider does not have useful semantics.");
69    }
70   
71  18 mutexes = new ReadWriteLockSync[numberOfStripes];
72   
73  36882 for (int i = 0; i < mutexes.length; i++) {
74  36864 mutexes[i] = new ReadWriteLockSync();
75    }
76  18 mutexesAsList = Collections.unmodifiableList(Arrays.asList(mutexes));
77    }
78   
79    /**
80    * Gets the Sync Stripe to use for a given key.
81    * <p/>
82    * This lookup must always return the same Sync for a given key.
83    * <p/>
84    * @param key the key
85    * @return one of a limited number of Sync's.
86    */
 
87  44 toggle public ReadWriteLockSync getSyncForKey(final Object key) {
88  44 int lockNumber = ConcurrencyUtil.selectLock(key, mutexes.length);
89  44 return mutexes[lockNumber];
90    }
91   
92    /**
93    * Gets the RWL Stripe to use for a given key.
94    * <p/>
95    * This lookup must always return the same RWL for a given key.
96    * <p/>
97    * @param key the key
98    * @return one of a limited number of RWLs.
99    */
 
100  0 toggle public ReadWriteLock getLockForKey(final Object key) {
101  0 int lockNumber = ConcurrencyUtil.selectLock(key, mutexes.length);
102  0 return mutexes[lockNumber].getReadWriteLock();
103    }
104   
105    /**
106    * Returns all internal syncs.
107    * @return all internal syncs
108    */
 
109    toggle public List<ReadWriteLockSync> getAllSyncs() {
110    return mutexesAsList;
111    }
112    }