() {
+ public Integer call() throws Exception {
+ int i = 0;
+ while (i++ < 50) {
+ System.gc();
+ assertThat(map.get(someKey), nullValue());
+ }
+ return cleanedUpValues.size();
+ }
+ }, Is.is(1));
+
+ assertThat(cleanedUpValues.get(value2), notNullValue());
+ assertThat(cleanedUpValues.get(value2).get(), is(1L));
+ }
+}
Index: rctags/ehcache-2.10.9.0.363/terracotta/bootstrap/src/main/java/org/terracotta/modules/ehcache/async/AsyncConfig.java
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/terracotta/bootstrap/src/main/java/org/terracotta/modules/ehcache/async/AsyncConfig.java (revision 0)
+++ rctags/ehcache-2.10.9.0.363/terracotta/bootstrap/src/main/java/org/terracotta/modules/ehcache/async/AsyncConfig.java (revision 11330)
@@ -0,0 +1,78 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ */
+package org.terracotta.modules.ehcache.async;
+
+import java.io.Serializable;
+
+public interface AsyncConfig extends Serializable {
+ /**
+ * Returns the minimum amount of time to wait between individual work cycles.
+ *
+ * This allows work to accumulate in the write behind queue and be processed more efficiently.
+ *
+ * @return the work delay that should be used, in milliseconds
+ */
+ public long getWorkDelay();
+
+ /**
+ * The maximum amount of time that a queue is allowed to fall behind on the work that it's processing.
+ *
+ * @return the maximum of time that the queue is allowed to fall behind, in milliseconds
+ */
+ public long getMaxAllowedFallBehind();
+
+ /**
+ * The number of items to include in each batch when batching is enabled. If there are less entries in the queue than
+ * the batch size, the queue length size is used.
+ *
+ * @return the amount of items to batch
+ */
+ public int getBatchSize();
+
+ /**
+ * Indicates whether to batch items. If set to {@code true}, {@link ItemProcessor#process(java.util.Collection)} will
+ * be called rather than {@link ItemProcessor#process(Serializable)} being called for individual item. Resources such as
+ * databases can perform more efficiently if updates are batched, thus reducing load.
+ *
+ * @return {@code true} if items should be batched; {@code false} otherwise
+ */
+ public boolean isBatchingEnabled();
+
+ /**
+ * Perform all writes to the Terracotta backend in a synchronous fashion, hence increasing reliability but decreasing
+ * performance.
+ *
+ * @return {@code true} to enable synchronous writes; or {@code false} to perform the write asynchronously
+ */
+ public boolean isSynchronousWrite();
+
+ /**
+ * Retrieves the number of times the processing of an item is retried.
+ *
+ * @return the number of tries before this pass is considered failed
+ */
+ public int getRetryAttempts();
+
+ /**
+ * Retrieves the number of milliseconds to wait before retrying a failed operation.
+ *
+ * @return the delay in between retries, in milliseconds
+ */
+ public long getRetryAttemptDelay();
+
+ /**
+ * Sets the maximum number of operations to allow per second when {@link #isBatchingEnabled} is enabled.
+ *
+ * @return the rate limit
+ */
+ public int getRateLimit();
+
+ /**
+ * The maximum size of items the Async coordinator can hold.
+ *
+ * @return
+ */
+ public int getMaxQueueSize();
+
+}
Index: rctags/ehcache-2.10.9.0.363/ehcache-core/src/test/java/net/sf/ehcache/store/disk/SegmentTest.java
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/ehcache-core/src/test/java/net/sf/ehcache/store/disk/SegmentTest.java (revision 0)
+++ rctags/ehcache-2.10.9.0.363/ehcache-core/src/test/java/net/sf/ehcache/store/disk/SegmentTest.java (revision 11330)
@@ -0,0 +1,43 @@
+package net.sf.ehcache.store.disk;
+
+import net.sf.ehcache.CacheOperationOutcomes;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.event.CacheEventListener;
+import net.sf.ehcache.event.RegisteredEventListeners;
+import net.sf.ehcache.pool.PoolAccessor;
+
+import org.junit.Test;
+import org.terracotta.statistics.observer.OperationObserver;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * SegmentTest
+ */
+public class SegmentTest {
+
+ @Test
+ public void testInlineEvictionNotified() {
+ PoolAccessor onHeapAccessor = mock(PoolAccessor.class);
+ when(onHeapAccessor.add(eq("key"), any(DiskStorageFactory.DiskSubstitute.class), any(HashEntry.class), eq(false))).thenReturn(-1L);
+ RegisteredEventListeners cacheEventNotificationService = new RegisteredEventListeners(mock(Ehcache.class), null);
+ CacheEventListener listener = mock(CacheEventListener.class);
+ cacheEventNotificationService.registerListener(listener);
+
+ OperationObserver evictionObserver = mock(OperationObserver.class);
+ DiskStorageFactory diskStorageFactory = mock(DiskStorageFactory.class);
+
+ Segment segment = new Segment(10, .95f, diskStorageFactory, mock(CacheConfiguration.class), onHeapAccessor, mock(PoolAccessor.class), cacheEventNotificationService, evictionObserver);
+ Element element = new Element("key", "value");
+ when(diskStorageFactory.create(element)).thenReturn(new DiskStorageFactory.DiskMarker(diskStorageFactory, 0L, 0, element));
+ segment.put("key", 12, element, false, false);
+ verify(listener).notifyElementEvicted(any(Ehcache.class), eq(element));
+ verify(evictionObserver).end(CacheOperationOutcomes.EvictionOutcome.SUCCESS);
+ }
+}
Index: rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/statistics/beans/AttributeProxy.java
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/statistics/beans/AttributeProxy.java (revision 0)
+++ rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/statistics/beans/AttributeProxy.java (revision 11330)
@@ -0,0 +1,116 @@
+/**
+ * Copyright Terracotta, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.ehcache.statistics.beans;
+
+/**
+ * The Class AttributeProxy, used to proxy operations from a dynamic mbean to a POJO object.
+ * Override get()/set() as needed.
+ *
+ * @param the return type/set type for the attribute
+ *
+ * @author cschanck
+ */
+public abstract class AttributeProxy {
+ private final String name;
+ private final Class clazz;
+ private final boolean isWrite;
+ private final boolean isRead;
+ private final String description;
+
+ /**
+ * Instantiates a new attribute proxy.
+ *
+ * @param clazz the clazz of the return type
+ * @param name the name
+ * @param description the description
+ * @param isRead readable
+ * @param isWrite writable
+ */
+ public AttributeProxy(Class clazz, String name, String description, boolean isRead, boolean isWrite) {
+ this.name = name;
+ this.description = description;
+ this.clazz = clazz;
+ this.isWrite = isWrite;
+ this.isRead = isRead;
+ }
+
+ /**
+ * Gets the description.
+ *
+ * @return the description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Gets the type class.
+ *
+ * @return the type class
+ */
+ public Class> getTypeClass() {
+ return clazz;
+ }
+
+ /**
+ * Gets the name.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the value.
+ *
+ * @param name the name
+ * @return the value
+ */
+ public T get(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the value.
+ *
+ * @param name the name
+ * @param t the value
+ */
+ public void set(String name, T t) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Checks if is readable.
+ *
+ * @return true, if is read
+ */
+ public boolean isRead() {
+ return isRead;
+ }
+
+ /**
+ * Checks if is writable.
+ *
+ * @return true, if is writable
+ */
+ public boolean isWrite() {
+ return isWrite;
+ }
+
+}
Index: rctags/ehcache-2.10.9.0.363/ehcache/src/main/resources/META-INF/terracotta/public-api-types
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/ehcache/src/main/resources/META-INF/terracotta/public-api-types (revision 0)
+++ rctags/ehcache-2.10.9.0.363/ehcache/src/main/resources/META-INF/terracotta/public-api-types (revision 11330)
@@ -0,0 +1 @@
+# Don't remove this line -- if file is empty then everything will become an API type
Index: rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/hibernate/management/impl/BaseEmitterBean.java
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/hibernate/management/impl/BaseEmitterBean.java (revision 0)
+++ rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/hibernate/management/impl/BaseEmitterBean.java (revision 11330)
@@ -0,0 +1,168 @@
+/**
+ * Copyright Terracotta, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.ehcache.hibernate.management.impl;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.StandardMBean;
+
+/**
+ * @author gkeim
+ *
+ */
+public abstract class BaseEmitterBean extends StandardMBean implements NotificationEmitter {
+ /**
+ * emitter
+ */
+ protected final Emitter emitter = new Emitter();
+
+ /**
+ * sequenceNumber
+ */
+ protected final AtomicLong sequenceNumber = new AtomicLong();
+
+
+ private final List notificationListeners = new CopyOnWriteArrayList();
+
+ /**
+ * BaseEmitterBean
+ *
+ * @param
+ * @param mbeanInterface
+ * @throws NotCompliantMBeanException
+ */
+ protected BaseEmitterBean(Class mbeanInterface) throws NotCompliantMBeanException {
+ super(mbeanInterface);
+ }
+
+ /**
+ * sendNotification
+ *
+ * @param eventType
+ */
+ public void sendNotification(String eventType) {
+ sendNotification(eventType, null, null);
+ }
+
+ /**
+ * sendNotification
+ *
+ * @param eventType
+ * @param data
+ */
+ public void sendNotification(String eventType, Object data) {
+ sendNotification(eventType, data, null);
+ }
+
+ /**
+ * sendNotification
+ *
+ * @param eventType
+ * @param data
+ * @param msg
+ */
+ public void sendNotification(String eventType, Object data, String msg) {
+ Notification notif = new Notification(eventType, this, sequenceNumber.incrementAndGet(), System.currentTimeMillis(), msg);
+ if (data != null) {
+ notif.setUserData(data);
+ }
+ emitter.sendNotification(notif);
+ }
+
+ /**
+ * Dispose of this SampledCacheManager and clean up held resources
+ */
+ public final void dispose() {
+ doDispose();
+ removeAllNotificationListeners();
+ }
+
+ /**
+ * Dispose callback of subclasses
+ */
+ protected abstract void doDispose();
+
+ /**
+ * @author gkeim
+ */
+ private class Emitter extends NotificationBroadcasterSupport {
+ /**
+ * @see javax.management.NotificationBroadcasterSupport#getNotificationInfo()
+ */
+ @Override
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ return BaseEmitterBean.this.getNotificationInfo();
+ }
+ }
+
+ /**
+ * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener,
+ * javax.management.NotificationFilter, java.lang.Object)
+ */
+ public void addNotificationListener(NotificationListener notif, NotificationFilter filter, Object callBack) {
+ emitter.addNotificationListener(notif, filter, callBack);
+ notificationListeners.add(notif);
+ }
+
+ /**
+ * remove all added notification listeners
+ */
+ private void removeAllNotificationListeners() {
+ for (NotificationListener listener : notificationListeners) {
+ try {
+ emitter.removeNotificationListener(listener);
+ } catch (ListenerNotFoundException e) {
+ // ignore
+ }
+ }
+ notificationListeners.clear();
+ }
+
+ /**
+ * @see javax.management.NotificationBroadcaster#getNotificationInfo()
+ */
+ public abstract MBeanNotificationInfo[] getNotificationInfo();
+
+
+ /**
+ * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
+ */
+ public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
+ emitter.removeNotificationListener(listener);
+ notificationListeners.remove(listener);
+ }
+
+ /**
+ * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener,
+ * javax.management.NotificationFilter, java.lang.Object)
+ */
+ public void removeNotificationListener(NotificationListener notif, NotificationFilter filter, Object callBack)
+ throws ListenerNotFoundException {
+ emitter.removeNotificationListener(notif, filter, callBack);
+ notificationListeners.remove(notif);
+ }
+}
Index: rctags/ehcache-2.10.9.0.363/system-tests/src/test/resources/hibernate-config/nontransactional/domain/HolidayCalendar.hbm.xml
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/system-tests/src/test/resources/hibernate-config/nontransactional/domain/HolidayCalendar.hbm.xml (revision 0)
+++ rctags/ehcache-2.10.9.0.363/system-tests/src/test/resources/hibernate-config/nontransactional/domain/HolidayCalendar.hbm.xml (revision 11330)
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: rctags/ehcache-2.10.9.0.363/management-ehcache-v2/src/main/java/net/sf/ehcache/management/resource/CacheEntityV2.java
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/management-ehcache-v2/src/main/java/net/sf/ehcache/management/resource/CacheEntityV2.java (revision 0)
+++ rctags/ehcache-2.10.9.0.363/management-ehcache-v2/src/main/java/net/sf/ehcache/management/resource/CacheEntityV2.java (revision 11330)
@@ -0,0 +1,23 @@
+/* All content copyright (c) 2003-2012 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.*/
+
+package net.sf.ehcache.management.resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ *
+ * An entity representing a cache resource from the management API.
+ *
+ *
+ * @author brandony
+ *
+ */
+public class CacheEntityV2 extends AbstractCacheEntityV2 {
+ private Map attributes = new HashMap();
+
+ public Map getAttributes() {
+ return attributes;
+ }
+}
Index: rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/store/chm/SelectableConcurrentHashMap.java
===================================================================
diff -u -N
--- rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/store/chm/SelectableConcurrentHashMap.java (revision 0)
+++ rctags/ehcache-2.10.9.0.363/ehcache-core/src/main/java/net/sf/ehcache/store/chm/SelectableConcurrentHashMap.java (revision 11330)
@@ -0,0 +1,1259 @@
+/**
+ * Copyright Terracotta, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.sf.ehcache.store.chm;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import net.sf.ehcache.CacheOperationOutcomes.EvictionOutcome;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.event.RegisteredEventListeners;
+import net.sf.ehcache.pool.PoolAccessor;
+import org.terracotta.statistics.observer.OperationObserver;
+
+import static net.sf.ehcache.statistics.StatisticBuilder.operation;
+
+/**
+ * SelectableConcurrentHashMap subclasses a repackaged version of ConcurrentHashMap
+ * ito allow efficient random sampling of the map values.
+ *
+ * The random sampling technique involves randomly selecting a map Segment, and then
+ * selecting a number of random entry chains from that segment.
+ *
+ * @author Chris Dennis
+ */
+@SuppressWarnings("ForLoopReplaceableByForEach")
+public class SelectableConcurrentHashMap {
+
+ /**
+ * The default initial capacity for this table,
+ * used when not otherwise specified in a constructor.
+ */
+ static final int DEFAULT_INITIAL_CAPACITY = 16;
+
+ /**
+ * The default load factor for this table, used when not
+ * otherwise specified in a constructor.
+ */
+ static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+ /**
+ * The maximum capacity, used if a higher value is implicitly
+ * specified by either of the constructors with arguments. MUST
+ * be a power of two <= 1<<30 to ensure that entries are indexable
+ * using ints.
+ */
+ private static final int MAXIMUM_CAPACITY = 1 << 30;
+
+ /**
+ * The maximum number of segments to allow; used to bound
+ * constructor arguments.
+ */
+ private static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
+
+ /**
+ * Number of unsynchronized retries in size and containsValue
+ * methods before resorting to locking. This is used to avoid
+ * unbounded retries if tables undergo continuous modification
+ * which would make it impossible to obtain an accurate result.
+ */
+ private static final int RETRIES_BEFORE_LOCK = 2;
+
+ /**
+ * Mask value for indexing into segments. The upper bits of a
+ * key's hash code are used to choose the segment.
+ */
+ private final int segmentMask;
+
+ /**
+ * Shift value for indexing within segments.
+ */
+ private final int segmentShift;
+
+ /**
+ * The segments, each of which is a specialized hash table
+ */
+ private final Segment[] segments;
+
+ private final Random rndm = new Random();
+ private final PoolAccessor poolAccessor;
+ private volatile long maxSize;
+ private final RegisteredEventListeners cacheEventNotificationService;
+
+ private Set