/core/src/main/java/org/infinispan/persistence/support/Bucket.java

http://github.com/infinispan/infinispan · Java · 146 lines · 114 code · 22 blank · 10 comment · 24 complexity · 42d08fb805a400acbca09879d57a1688 MD5 · raw file

  1. package org.infinispan.persistence.support;
  2. import java.util.HashMap;
  3. import java.util.HashSet;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6. import java.util.Set;
  7. import org.infinispan.commons.equivalence.AnyEquivalence;
  8. import org.infinispan.commons.equivalence.Equivalence;
  9. import org.infinispan.commons.util.CollectionFactory;
  10. import org.infinispan.filter.KeyFilter;
  11. import org.infinispan.marshall.core.MarshalledEntry;
  12. import org.infinispan.persistence.PersistenceUtil;
  13. import org.infinispan.util.TimeService;
  14. /**
  15. * A bucket is where entries are stored.
  16. */
  17. public final class Bucket {
  18. final Map<Object, MarshalledEntry> entries;
  19. private transient Integer bucketId;
  20. private transient String bucketIdStr;
  21. public Bucket(Equivalence<Object> keyEquivalence) {
  22. this.entries = CollectionFactory.makeMap(32, keyEquivalence, AnyEquivalence.<MarshalledEntry>getInstance());
  23. }
  24. public Bucket(Map<Object, MarshalledEntry> entries, Equivalence<Object> keyEquivalence) {
  25. this.entries = CollectionFactory.makeMap(entries, keyEquivalence, AnyEquivalence.<MarshalledEntry>getInstance());
  26. }
  27. public final void addEntry(Object key,MarshalledEntry sv) {
  28. entries.put(key, sv);
  29. }
  30. public final boolean removeEntry(Object key) {
  31. return entries.remove(key) != null;
  32. }
  33. public final MarshalledEntry getEntry(Object key, TimeService timeService) {
  34. MarshalledEntry marshalledEntry = entries.get(key);
  35. if (marshalledEntry == null)
  36. return null;
  37. if (marshalledEntry.getMetadata() != null && marshalledEntry.getMetadata().isExpired(timeService.wallClockTime())) {
  38. return null;
  39. }
  40. return marshalledEntry;
  41. }
  42. public Integer getBucketId() {
  43. return bucketId;
  44. }
  45. public void setBucketId(Integer bucketId) {
  46. this.bucketId = bucketId;
  47. bucketIdStr = bucketId.toString();
  48. }
  49. public void setBucketId(String bucketId) {
  50. try {
  51. setBucketId(Integer.parseInt(bucketId));
  52. } catch (NumberFormatException e) {
  53. throw new IllegalArgumentException(
  54. "bucketId: " + bucketId + " (expected: integer)");
  55. }
  56. }
  57. public String getBucketIdAsString() {
  58. return bucketIdStr;
  59. }
  60. public Set<Object> removeExpiredEntries(TimeService timeService) {
  61. Set<Object> result = new HashSet<Object>();
  62. long currentTimeMillis = 0;
  63. Iterator<Map.Entry<Object, MarshalledEntry>> entryIterator = entries.entrySet().iterator();
  64. while (entryIterator.hasNext()) {
  65. Map.Entry<Object, MarshalledEntry> entry = entryIterator.next();
  66. final MarshalledEntry value = entry.getValue();
  67. if (value.getMetadata() != null) {
  68. if (currentTimeMillis == 0)
  69. currentTimeMillis = timeService.wallClockTime();
  70. if (value.getMetadata().isExpired(currentTimeMillis)) {
  71. result.add(entry.getKey());
  72. entryIterator.remove();
  73. }
  74. }
  75. }
  76. return result;
  77. }
  78. public Map<Object, MarshalledEntry> getStoredEntries() {
  79. return entries;
  80. }
  81. public Map<Object, MarshalledEntry> getStoredEntries(KeyFilter filter, TimeService timeService) {
  82. filter = PersistenceUtil.notNull(filter);
  83. long currentTimeMillis = timeService.wallClockTime();
  84. Map<Object, MarshalledEntry> result = new HashMap<Object, MarshalledEntry>();
  85. for (Map.Entry<Object, MarshalledEntry> entry : getStoredEntries().entrySet()) {
  86. MarshalledEntry me = entry.getValue();
  87. if (!isExpired(currentTimeMillis, me) && filter.accept(entry.getKey()))
  88. result.put(entry.getKey(), me);
  89. }
  90. return result;
  91. }
  92. private boolean isExpired(long currentTimeMillis, MarshalledEntry me) {
  93. return me != null && me.getMetadata() != null && me.getMetadata().isExpired(currentTimeMillis);
  94. }
  95. public long timestampOfFirstEntryToExpire() {
  96. long result = Long.MAX_VALUE;
  97. for (MarshalledEntry se : entries.values()) {
  98. if (se.getMetadata() != null && se.getMetadata().expiryTime() < result) {
  99. result = se.getMetadata().expiryTime();
  100. }
  101. }
  102. return result;
  103. }
  104. @Override
  105. public String toString() {
  106. return "Bucket{" +
  107. "entries=" + entries +
  108. ", bucketId='" + bucketId + '\'' +
  109. '}';
  110. }
  111. public boolean isEmpty() {
  112. return entries.isEmpty();
  113. }
  114. public boolean contains(Object key, TimeService timeService) {
  115. return getEntry(key, timeService) != null;
  116. }
  117. // Bucket externalizer has been removed because it's no longer marshallable.
  118. // The reason for this is cos the bucket's entry collection must take
  119. // into account cache-level configured equivalence instances, and passing
  120. // this in to an externalizer, which is a cache manager level abstraction
  121. // complicated things a lot. Instead, bucket's entries are now marshalled
  122. // separately and since that's the only thing that the bucket marshalled,
  123. // it's a pretty small change.
  124. }