Coverage Report - de.jollyday.util.Cache
 
Classes in this File Line Coverage Branch Coverage Complexity
Cache
90%
36/40
100%
8/8
1,357
Cache$ValueHandler
N/A
N/A
1,357
 
 1  
 /**
 2  
  * Copyright 2013 Sven Diedrichsen
 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
 12  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 13  
  * express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package de.jollyday.util;
 17  
 
 18  
 import java.util.HashMap;
 19  
 import java.util.Map;
 20  
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 21  
 
 22  
 /**
 23  
  * Cache implementation which handles concurrent access to cached values.
 24  
  *
 25  
  * @param <VALUE>
 26  
  *            the type of cached values
 27  
  */
 28  77
 public class Cache<VALUE> {
 29  
         /**
 30  
          * Map for caching
 31  
          */
 32  77
         private Map<String, VALUE> cachingMap = new HashMap<>();
 33  
         /**
 34  
          * Lock for accessing the map
 35  
          */
 36  77
         private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 37  
         /**
 38  
          * Returns the value defined by the {@link ValueHandler}
 39  
          *
 40  
          * @param valueHandler
 41  
          *            which creates the key and the value if necessary
 42  
          * @return the eventually cached value
 43  
          */
 44  
         public VALUE get(ValueHandler<VALUE> valueHandler) {
 45  2355
                 String key = valueHandler.getKey();
 46  
                 try {
 47  2359
                         readLock();
 48  2355
                         if (!containsKey(key)) {
 49  85
                                 readUnlockWriteLock();
 50  86
                                 if (!containsKey(key)) {
 51  79
                                         putValue(key, valueHandler.createValue());
 52  
                                 }
 53  84
                                 readLockWriteUnlock();
 54  
                         }
 55  2353
                         return getValue(key);
 56  
                 } finally {
 57  2350
                         unlockBoth();
 58  
                 }
 59  
         }
 60  
 
 61  
         private void unlockBoth() {
 62  2353
                 writeUnlock();
 63  2349
                 readUnlock();
 64  2356
         }
 65  
 
 66  
         private void readLockWriteUnlock() {
 67  84
                 readLock();
 68  84
                 writeUnlock();
 69  84
         }
 70  
 
 71  
         private void readUnlockWriteLock() {
 72  85
                 readUnlock();
 73  86
                 writeLock();
 74  86
         }
 75  
 
 76  
         private VALUE getValue(String key) {
 77  2348
                 return cachingMap.get(key);
 78  
         }
 79  
 
 80  
         private void putValue(String key, VALUE value) {
 81  77
                 cachingMap.put(key, value);
 82  77
         }
 83  
 
 84  
         private boolean containsKey(String key) {
 85  2433
                 return cachingMap.containsKey(key);
 86  
         }
 87  
 
 88  
         private void writeUnlock() {
 89  2429
                 if (lock.isWriteLockedByCurrentThread()) {
 90  86
                         lock.writeLock().unlock();
 91  
                 }
 92  2434
         }
 93  
 
 94  
         private void writeLock() {
 95  86
                 lock.writeLock().lock();
 96  86
         }
 97  
 
 98  
         private void readLock() {
 99  2441
                 lock.readLock().lock();
 100  2437
         }
 101  
 
 102  
         private void readUnlock() {
 103  2432
                 if(lock.getReadHoldCount() > 0){
 104  2434
                         lock.readLock().unlock();
 105  
                 }
 106  2446
         }
 107  
 
 108  
         /**
 109  
          * Clears the cache.
 110  
          */
 111  
         public void clear() {
 112  0
                 writeLock();
 113  0
                 cachingMap.clear();
 114  0
                 writeUnlock();
 115  0
         }
 116  
 
 117  77
         public interface ValueHandler<VALUE> {
 118  
                 String getKey();
 119  
                 VALUE createValue();
 120  
         }
 121  
 
 122  
 }