/src/com/j256/ormlite/dao/ReferenceObjectCache.java

https://code.google.com/ · Java · 148 lines · 106 code · 18 blank · 24 comment · 17 complexity · c0fcf5f31d2733beae6bc032ba3db416 MD5 · raw file

  1. package com.j256.ormlite.dao;
  2. import java.lang.ref.Reference;
  3. import java.lang.ref.SoftReference;
  4. import java.lang.ref.WeakReference;
  5. import java.util.Iterator;
  6. import java.util.Map;
  7. import java.util.Map.Entry;
  8. import java.util.concurrent.ConcurrentHashMap;
  9. /**
  10. * Cache for ORMLite which stores objects with a {@link WeakReference} or {@link SoftReference} to them. Java Garbage
  11. * Collection can then free these objects if no one has a "strong" reference to the object (weak) or if it runs out of
  12. * memory (soft).
  13. *
  14. * @author graywatson
  15. */
  16. public class ReferenceObjectCache implements ObjectCache {
  17. private final ConcurrentHashMap<Class<?>, Map<Object, Reference<Object>>> classMaps =
  18. new ConcurrentHashMap<Class<?>, Map<Object, Reference<Object>>>();
  19. private final boolean useWeak;
  20. /**
  21. * @param useWeak
  22. * Set to true if you want the cache to use {@link WeakReference}. If false then the cache will use
  23. * {@link SoftReference}.
  24. */
  25. public ReferenceObjectCache(boolean useWeak) {
  26. this.useWeak = useWeak;
  27. }
  28. /**
  29. * Create and return an object cache using {@link WeakReference}.
  30. */
  31. public static ReferenceObjectCache makeWeakCache() {
  32. return new ReferenceObjectCache(true);
  33. }
  34. /**
  35. * Create and return an object cache using {@link SoftReference}.
  36. */
  37. public static ReferenceObjectCache makeSoftCache() {
  38. return new ReferenceObjectCache(false);
  39. }
  40. public <T, ID> T get(Class<T> clazz, ID id) {
  41. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  42. Reference<Object> ref = objectMap.get(id);
  43. if (ref == null) {
  44. return null;
  45. }
  46. Object obj = ref.get();
  47. if (obj == null) {
  48. objectMap.remove(id);
  49. return null;
  50. } else {
  51. @SuppressWarnings("unchecked")
  52. T castObj = (T) obj;
  53. return castObj;
  54. }
  55. }
  56. public <T, ID> void put(Class<T> clazz, ID id, T data) {
  57. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  58. if (useWeak) {
  59. objectMap.put(id, new WeakReference<Object>(data));
  60. } else {
  61. objectMap.put(id, new SoftReference<Object>(data));
  62. }
  63. }
  64. public <T> void clear(Class<T> clazz) {
  65. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  66. objectMap.clear();
  67. }
  68. public void clearAll() {
  69. for (Map<Object, Reference<Object>> objectMap : classMaps.values()) {
  70. objectMap.clear();
  71. }
  72. }
  73. public <T, ID> void remove(Class<T> clazz, ID id) {
  74. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  75. objectMap.remove(id);
  76. }
  77. public <T, ID> T updateId(Class<T> clazz, ID oldId, ID newId) {
  78. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  79. Reference<Object> ref = objectMap.remove(oldId);
  80. if (ref == null) {
  81. return null;
  82. }
  83. objectMap.put(newId, ref);
  84. @SuppressWarnings("unchecked")
  85. T castObj = (T) ref.get();
  86. return castObj;
  87. }
  88. public <T> int size(Class<T> clazz) {
  89. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  90. return objectMap.size();
  91. }
  92. public int sizeAll() {
  93. int size = 0;
  94. for (Map<Object, Reference<Object>> objectMap : classMaps.values()) {
  95. size += objectMap.size();
  96. }
  97. return size;
  98. }
  99. /**
  100. * Run through the map and remove any references that have been null'd out by the GC.
  101. */
  102. public <T> void cleanNullReferences(Class<T> clazz) {
  103. Map<Object, Reference<Object>> objectMap = getMapForClass(clazz);
  104. cleanMap(objectMap);
  105. }
  106. /**
  107. * Run through all maps and remove any references that have been null'd out by the GC.
  108. */
  109. public <T> void cleanNullReferencesAll() {
  110. for (Map<Object, Reference<Object>> objectMap : classMaps.values()) {
  111. cleanMap(objectMap);
  112. }
  113. }
  114. private void cleanMap(Map<Object, Reference<Object>> objectMap) {
  115. Iterator<Entry<Object, Reference<Object>>> iterator = objectMap.entrySet().iterator();
  116. while (iterator.hasNext()) {
  117. if (iterator.next().getValue().get() == null) {
  118. iterator.remove();
  119. }
  120. }
  121. }
  122. private Map<Object, Reference<Object>> getMapForClass(Class<?> clazz) {
  123. Map<Object, Reference<Object>> objectMap = classMaps.get(clazz);
  124. if (objectMap == null) {
  125. objectMap = new ConcurrentHashMap<Object, Reference<Object>>();
  126. classMaps.put(clazz, objectMap);
  127. }
  128. return objectMap;
  129. }
  130. }