Author: julien_viet
Date: 2009-11-16 02:39:24 -0500 (Mon, 16 Nov 2009)
New Revision: 603
Added:
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/AtomicPositiveLong.java
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/BoundedBuffer.java
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/LongSampler.java
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/ObjectRef.java
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/AtomicPositiveLongTestCase.java
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/BoundedBufferTestCase.java
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/LongSamplerTestCase.java
Log:
GTNCOMMON-6 : copied the concurrent classes from GateIn portal to GateIn common
Added:
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/AtomicPositiveLong.java
===================================================================
---
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/AtomicPositiveLong.java
(rev 0)
+++
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/AtomicPositiveLong.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Extends the @link{AtomicLong} to contain positive longs. If no initial value
+ * is provided when the object is created then the value is -1 to indicate that
+ * it is not yet initialized.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class AtomicPositiveLong extends AtomicLong
+{
+
+ /**
+ * Create an atomic positive long with an inital provided value.
+ *
+ * @param initialValue the initial value
+ * @throws IllegalArgumentException if the value is negative
+ */
+ public AtomicPositiveLong(long initialValue) throws IllegalArgumentException
+ {
+ super(initialValue);
+
+ //
+ if (initialValue == -1)
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Create an atomic positive long with no initial value.
+ */
+ public AtomicPositiveLong()
+ {
+ super(-1);
+ }
+
+ /**
+ * Update the value if the new value is greater than the previous one or if the long
is not initialized.
+ *
+ * @param newValue the new value
+ * @throws IllegalArgumentException if the new value is negative
+ */
+ public void setIfGreater(long newValue) throws IllegalArgumentException
+ {
+ if (newValue < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ while (true)
+ {
+ long oldValue = get();
+ if (newValue > oldValue || oldValue == -1)
+ {
+ compareAndSet(oldValue, newValue);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Update the value if the new value is lower than the previous one or if the long is
not initialized.
+ *
+ * @param newValue the new value
+ * @throws IllegalArgumentException if the new value is negative
+ */
+ public void setIfLower(long newValue) throws IllegalArgumentException
+ {
+ if (newValue < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ while (true)
+ {
+ long oldValue = get();
+ if (newValue < oldValue || oldValue == -1)
+ {
+ compareAndSet(oldValue, newValue);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+}
Added:
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/BoundedBuffer.java
===================================================================
---
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/BoundedBuffer.java
(rev 0)
+++
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/BoundedBuffer.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * <p>A thread safe bounded buffer.</p>
+ *
+ * <p>The idea of this class is that it retains only the last elements added
+ * to the buffer up to a determined size, but it is possible to make snapshot of the
buffer elements and iterate
+ * over them with a neglectable impact on synchronization.</p>
+ *
+ * <p>It maintains a linked list. When a new element is added, the first element
will have for
+ * successor that new element. If the number of elements is greater than the max size
then the last element
+ * is discarded.</p>
+ *
+ * <p> When a snapshot for iteration is required, the class only needs to keep a
reference to the last element of the list
+ * and keep also the actual size of the list. The copy is made in an atomic manner for
consistency. Note that this class
+ * expose only a notion of iterator to its client instead of a notion of list as iterator
have a notion of being short
+ * lived objects. Indeed keeping a reference on an iterator would create a memory leak
and so this class must be used
+ * with caution.</p>
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ * @todo develop a non blocking implementation pretty much like the ConcurrentLinkedQueue
does
+ * @todo although I don't think this class is a bottleneck as there is very short
lived synchronization
+ * @todo and actually I don't know if it's feasible to have a non blocking impl
due to the size value
+ *
+ */
+public class BoundedBuffer<T> implements Iterable<T>
+{
+
+ /** The max size. */
+ private final int maxSize;
+
+ /** The elder element. */
+ private ObjectRef<T> last;
+
+ /** The younger element. */
+ private ObjectRef<T> first;
+
+ /** The size, it is declared as volatile for the @link{getSize()} method. */
+ private volatile int size;
+
+ public BoundedBuffer(int maxSize)
+ {
+ if (maxSize < 1)
+ {
+ throw new IllegalArgumentException("Buffer size needs to be greater than
zero");
+ }
+
+ //
+ this.maxSize = maxSize;
+ this.size = 0;
+ }
+
+ public int getMaxSize()
+ {
+ return maxSize;
+ }
+
+ public int getSize()
+ {
+ return size;
+ }
+
+ /**
+ * Add an element to the buffer.
+ *
+ * @param t the element to add
+ */
+ public void add(T t)
+ {
+ synchronized (this)
+ {
+ if (first == null)
+ {
+ first = new ObjectRef<T>(t);
+ last = first;
+ size = 1;
+ }
+ else
+ {
+ ObjectRef<T> tmp = first;
+ first = new ObjectRef<T>(t);
+ tmp.next.set(first);
+ if (size < maxSize)
+ {
+ size++;
+ }
+ else
+ {
+ last = last.next.get();
+ }
+ }
+ }
+ }
+
+ /**
+ * Make a snapshot of the buffer and iterate over the elements. It is important to not
keep reference
+ * on an iterator returned by this method otherwise it could create a memory leak.
+ *
+ * @return an iterator over the elements
+ */
+ public Iterator<T> iterator()
+ {
+ if (size == 0)
+ {
+ List<T> empty = Collections.emptyList();
+ return empty.iterator();
+ }
+ else
+ {
+ // Get consistent state
+ final ObjectRef<T> lastSnapshot;
+ final int sizeSnapshot;
+ synchronized (this)
+ {
+ lastSnapshot = last;
+ sizeSnapshot = size;
+ }
+ return new BoundedIterator<T>(lastSnapshot, sizeSnapshot);
+ }
+ }
+
+ private static final class BoundedIterator<T> implements Iterator<T>
+ {
+
+ final int size;
+
+ ObjectRef<T> current;
+
+ int count = 0;
+
+ private BoundedIterator(ObjectRef<T> current, int size)
+ {
+ this.current = current;
+ this.size = size;
+ this.count = 0;
+ }
+
+ public boolean hasNext()
+ {
+ return count < size && current != null;
+ }
+
+ public T next()
+ {
+ if (!hasNext())
+ {
+ throw new NoSuchElementException();
+ }
+ T next = current.object;
+ current = current.next.get();
+ count++;
+ return next;
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
Added:
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/LongSampler.java
===================================================================
---
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/LongSampler.java
(rev 0)
+++
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/LongSampler.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+/**
+ * An object that sample long values.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ * @todo move to common utils
+ */
+public class LongSampler extends BoundedBuffer<Long>
+{
+
+ public LongSampler(int maxSize)
+ {
+ super(maxSize);
+ }
+
+ /**
+ * Returns the average value.
+ *
+ * @return the average
+ */
+ public double average()
+ {
+ long sumTime = 0;
+ int size = 0;
+ for (long value : this)
+ {
+ sumTime += value;
+ size++;
+ }
+ return size == 0 ? 0 : (double)sumTime / (double)size;
+ }
+
+ /**
+ * Returns the number of values which are greater or equals to the threshold value.
+ *
+ * @param threshold the threshold value
+ * @return the count of values above the provided threshold
+ */
+ public int countAboveThreshold(long threshold)
+ {
+ int count = 0;
+ for (long value : this)
+ {
+ if (value >= threshold)
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+}
Added:
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/ObjectRef.java
===================================================================
---
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/ObjectRef.java
(rev 0)
+++
components/common/trunk/common/src/main/java/org/gatein/common/concurrent/ObjectRef.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * An internal class to keep a reference onto another object, it is used in the bounded
buffer implementation.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+class ObjectRef<T>
+{
+
+ /** . */
+ final T object;
+
+ /** . */
+ final AtomicReference<ObjectRef<T>> next;
+
+ ObjectRef(T object)
+ {
+ this.object = object;
+ this.next = new AtomicReference<ObjectRef<T>>();
+ }
+}
Added:
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/AtomicPositiveLongTestCase.java
===================================================================
---
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/AtomicPositiveLongTestCase.java
(rev 0)
+++
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/AtomicPositiveLongTestCase.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class AtomicPositiveLongTestCase extends TestCase
+{
+
+ public AtomicPositiveLongTestCase()
+ {
+ }
+
+ public AtomicPositiveLongTestCase(String s)
+ {
+ super(s);
+ }
+
+ public void testConstructorThrowsIAE()
+ {
+ try
+ {
+ new AtomicPositiveLong(-1);
+ fail();
+ }
+ catch (IllegalArgumentException expected)
+ {
+ }
+ }
+
+ public void testUpdateIfGreater1()
+ {
+ AtomicPositiveLong stat = new AtomicPositiveLong(4);
+ assertEquals(4, stat.get());
+ stat.setIfGreater(3);
+ assertEquals(4, stat.get());
+ stat.setIfGreater(5);
+ assertEquals(5, stat.get());
+ }
+
+ public void testUpdateIfGreater2()
+ {
+ AtomicPositiveLong stat = new AtomicPositiveLong();
+ assertEquals(-1, stat.get());
+ stat.setIfGreater(0);
+ assertEquals(0, stat.get());
+ }
+
+ public void testUpdateIfGreaterThrowsIAE()
+ {
+ AtomicPositiveLong stat = new AtomicPositiveLong(4);
+ try
+ {
+ stat.setIfGreater(-1);
+ }
+ catch (IllegalArgumentException expected)
+ {
+ assertEquals(4, stat.get());
+ }
+ }
+
+ public void testUpdateIfLowser1()
+ {
+ AtomicPositiveLong stat = new AtomicPositiveLong(4);
+ assertEquals(4, stat.get());
+ stat.setIfLower(5);
+ assertEquals(4, stat.get());
+ stat.setIfLower(3);
+ assertEquals(3, stat.get());
+ }
+
+ public void testUpdateIfLowser2()
+ {
+ AtomicPositiveLong stat = new AtomicPositiveLong();
+ assertEquals(-1, stat.get());
+ stat.setIfLower(0);
+ assertEquals(0, stat.get());
+ }
+
+ public void testUpdateIfLowerThrowsIAE()
+ {
+ AtomicPositiveLong stat = new AtomicPositiveLong(4);
+ try
+ {
+ stat.setIfLower(-1);
+ }
+ catch (IllegalArgumentException expected)
+ {
+ assertEquals(4, stat.get());
+ }
+ }
+}
Added:
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/BoundedBufferTestCase.java
===================================================================
---
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/BoundedBufferTestCase.java
(rev 0)
+++
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/BoundedBufferTestCase.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+import junit.framework.TestCase;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class BoundedBufferTestCase extends TestCase
+{
+
+ public BoundedBufferTestCase()
+ {
+ }
+
+ public BoundedBufferTestCase(String s)
+ {
+ super(s);
+ }
+
+ public void testNegativeMaxSize()
+ {
+ try
+ {
+ new BoundedBuffer<Object>(-1);
+ }
+ catch (IllegalArgumentException expected)
+ {
+ }
+ }
+
+ public void testSnapshot()
+ {
+ BoundedBuffer<Object> buffer = new BoundedBuffer<Object>(2);
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+ Iterator<Object> i0 = buffer.iterator();
+ buffer.add(o1);
+ Iterator<Object> i1 = buffer.iterator();
+ buffer.add(o2);
+ Iterator<Object> i2 = buffer.iterator();
+ buffer.add(o3);
+ Iterator<Object> i3 = buffer.iterator();
+ assertEquals(Arrays.asList(), toList(i0));
+ assertEquals(Arrays.asList(o1), toList(i1));
+ assertEquals(Arrays.asList(o1, o2), toList(i2));
+ assertEquals(Arrays.asList(o2, o3), toList(i3));
+ }
+
+ public void testNoLeak()
+ {
+ BoundedBuffer<Object> buffer = new BoundedBuffer<Object>(2);
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+ buffer.add(o1);
+ buffer.add(o2);
+ buffer.add(o3);
+ WeakReference<Object> ref1 = new WeakReference<Object>(o1);
+ WeakReference<Object> ref2 = new WeakReference<Object>(o2);
+ WeakReference<Object> ref3 = new WeakReference<Object>(o3);
+ o1 = null;
+ o2 = null;
+ o3 = null;
+ forceGC();
+ assertNull(ref1.get());
+ assertNotNull(ref2.get());
+ assertNotNull(ref3.get());
+ }
+
+ private <T> List<T> toList(Iterator<T> iterable)
+ {
+ List<T> list = new ArrayList<T>();
+ while (iterable.hasNext())
+ {
+ T t = iterable.next();
+ list.add(t);
+ }
+ return list;
+ }
+
+ /**
+ * Force a garbage collector.
+ */
+ protected static void forceGC()
+ {
+ WeakReference<Object> dumbReference = new WeakReference<Object>(new
Object());
+ // A loop that will wait GC, using the minimal time as possible
+ while (dumbReference.get() != null)
+ {
+ System.gc();
+ try
+ {
+ Thread.sleep(500);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+}
+
Added:
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/LongSamplerTestCase.java
===================================================================
---
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/LongSamplerTestCase.java
(rev 0)
+++
components/common/trunk/common/src/test/java/org/gatein/common/concurrent/LongSamplerTestCase.java 2009-11-16
07:39:24 UTC (rev 603)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.gatein.common.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class LongSamplerTestCase extends TestCase
+{
+
+ public LongSamplerTestCase()
+ {
+ }
+
+ public LongSamplerTestCase(String s)
+ {
+ super(s);
+ }
+
+ public void testAverage()
+ {
+ LongSampler sampler = new LongSampler(2);
+ sampler.add(2L);
+ sampler.add(4L);
+ assertEquals(3D, sampler.average());
+ sampler.add(8L);
+ assertEquals(6D, sampler.average());
+ }
+
+ public void testAboveThreshold()
+ {
+ LongSampler sampler = new LongSampler(2);
+ sampler.add(1L);
+ sampler.add(2L);
+ assertEquals(0, sampler.countAboveThreshold(3L));
+ assertEquals(1, sampler.countAboveThreshold(2L));
+ assertEquals(2, sampler.countAboveThreshold(1L));
+ assertEquals(2, sampler.countAboveThreshold(0L));
+ }
+}