/interpreter/tags/at2dist041108/src/edu/vub/at/objects/symbiosis/JMethodCache.java

http://ambienttalk.googlecode.com/ · Java · 119 lines · 49 code · 11 blank · 59 comment · 9 complexity · 9983109c70e7e6389f4dd8504d9f2409 MD5 · raw file

  1. /**
  2. * AmbientTalk/2 Project
  3. * JMethodCache.java created on 9-dec-2006 at 17:14:55
  4. * (c) Programming Technology Lab, 2006 - 2007
  5. * Authors: Tom Van Cutsem & Stijn Mostinckx
  6. *
  7. * Permission is hereby granted, free of charge, to any person
  8. * obtaining a copy of this software and associated documentation
  9. * files (the "Software"), to deal in the Software without
  10. * restriction, including without limitation the rights to use,
  11. * copy, modify, merge, publish, distribute, sublicense, and/or
  12. * sell copies of the Software, and to permit persons to whom the
  13. * Software is furnished to do so, subject to the following
  14. * conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be
  17. * included in all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  21. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  23. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  24. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  26. * OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. package edu.vub.at.objects.symbiosis;
  29. import java.lang.ref.SoftReference;
  30. import java.util.Collections;
  31. import java.util.Hashtable;
  32. import java.util.Map;
  33. /**
  34. * A singleton object that represents a method cache. It is used to speed up
  35. * the symbiosis with Java. Every time a JavaMethod is successfully created from
  36. * an array of java.lang.reflect.Method objects, it is stored in the cache.
  37. * The cache uses weak references such that JavaMethod instances can be safely recollected
  38. * when they are no longer used. Note that this caching scheme only works because:
  39. * - Java classes are unmodifyable at runtime
  40. * - JavaMethod objects are constant, so may be safely shared between different actors
  41. *
  42. * The method cache is implemented as a hash map, mapping pairs
  43. * [ java.lang.Class class, java.lang.String methodname, boolean isStatic ] => soft ref to JavaMethod
  44. *
  45. * If a JavaMethod has been garbage collected, its entry is removed from the cache.
  46. * Soft references rather than weak references are used to point to the JavaMethod entries.
  47. * Soft references are like weak references, but normally only get reclaimed when the
  48. * JVM runs low on memory. Hence, they are much more suitable for caching.
  49. *
  50. * The cache is synchronized to ensure proper synchronization between different actors.
  51. *
  52. * @author tvcutsem
  53. */
  54. public final class JMethodCache {
  55. public static final JMethodCache _INSTANCE_ = new JMethodCache();
  56. private final Map cache_;
  57. private JMethodCache() {
  58. cache_ = Collections.synchronizedMap(new Hashtable());
  59. }
  60. /**
  61. * Add a JavaMethod instance to the cache.
  62. */
  63. public void put(Class cls, String methName, boolean isStatic, JavaMethod entry) {
  64. cache_.put(new CacheKey(cls, methName, isStatic), new SoftReference(entry));
  65. }
  66. /**
  67. * Retrieve a JavaMethod entry from the cache.
  68. * @return the entry, or null if the cache does not contain the entry
  69. */
  70. public JavaMethod get(Class cls, String methName, boolean isStatic) {
  71. CacheKey key = new CacheKey(cls, methName, isStatic);
  72. SoftReference ref = (SoftReference) cache_.get(key);
  73. if (ref == null) {
  74. return null; // cache miss
  75. } else {
  76. JavaMethod entry = (JavaMethod) ref.get();
  77. if (entry != null) {
  78. // cache hit
  79. return entry;
  80. } else {
  81. // entry was garbage-collected, clean up the mapping
  82. cache_.remove(key);
  83. return null; // cache miss
  84. }
  85. }
  86. }
  87. private static class CacheKey {
  88. private final Class class_;
  89. private final String methodName_;
  90. private final boolean isStatic_;
  91. public CacheKey(Class c, String mname, boolean isStatic) {
  92. class_ = c;
  93. methodName_ = mname;
  94. isStatic_ = isStatic;
  95. }
  96. public boolean equals(Object other) {
  97. // no check on type of other for performance reasons:
  98. // these CacheKeys are not compared to anything else
  99. CacheKey otherKey = (CacheKey) other;
  100. return ((class_.equals(otherKey.class_))
  101. && (methodName_.equals(otherKey.methodName_))
  102. && (isStatic_ == otherKey.isStatic_));
  103. }
  104. public int hashCode() {
  105. return (class_.hashCode() | methodName_.hashCode()) << ((isStatic_) ? 1 : 0);
  106. }
  107. }
  108. }