[gatein-commits] gatein SVN: r603 - in components/common/trunk/common/src: test/java/org/gatein/common and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Nov 16 02:39:24 EST 2009


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 at 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 at 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 at 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 at 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 at 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 at 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 at 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));
+   }
+}



More information about the gatein-commits mailing list