]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/classes/core/src/com/ibm/icu/impl/locale/LocaleObjectCache.java
Added flags.
[Dictionary.git] / jars / icu4j-52_1 / main / classes / core / src / com / ibm / icu / impl / locale / LocaleObjectCache.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 2009-2010, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.impl.locale;
8
9 import java.lang.ref.ReferenceQueue;
10 import java.lang.ref.SoftReference;
11 import java.util.concurrent.ConcurrentHashMap;
12
13 public abstract class LocaleObjectCache<K, V> {
14     private ConcurrentHashMap<K, CacheEntry<K, V>> _map;
15     private ReferenceQueue<V> _queue = new ReferenceQueue<V>();
16
17     public LocaleObjectCache() {
18         this(16, 0.75f, 16);
19     }
20
21     public LocaleObjectCache(int initialCapacity, float loadFactor, int concurrencyLevel) {
22         _map = new ConcurrentHashMap<K, CacheEntry<K, V>>(initialCapacity, loadFactor, concurrencyLevel);
23     }
24
25     public V get(K key) {
26         V value = null;
27
28         cleanStaleEntries();
29         CacheEntry<K, V> entry = _map.get(key);
30         if (entry != null) {
31             value = entry.get();
32         }
33         if (value == null) {
34             key = normalizeKey(key);
35             V newVal = createObject(key);
36             if (key == null || newVal == null) {
37                 // subclass must return non-null key/value object
38                 return null;
39             }
40
41             CacheEntry<K, V> newEntry = new CacheEntry<K, V>(key, newVal, _queue);
42
43             while (value == null) {
44                 cleanStaleEntries();
45                 entry = _map.putIfAbsent(key, newEntry);
46                 if (entry == null) {
47                     value = newVal;
48                     break;
49                 } else {
50                     value = entry.get();
51                 }
52             }
53         }
54         return value;
55     }
56
57     @SuppressWarnings("unchecked")
58     private void cleanStaleEntries() {
59         CacheEntry<K, V> entry;
60         while ((entry = (CacheEntry<K, V>)_queue.poll()) != null) {
61             _map.remove(entry.getKey());
62         }
63     }
64
65     protected abstract V createObject(K key);
66
67     protected K normalizeKey(K key) {
68         return key;
69     }
70
71     private static class CacheEntry<K, V> extends SoftReference<V> {
72         private K _key;
73
74         CacheEntry(K key, V value, ReferenceQueue<V> queue) {
75             super(value, queue);
76             _key = key;
77         }
78
79         K getKey() {
80             return _key;
81         }
82     }
83 }