All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jagg.util.FunctionCache Maven / Gradle / Ivy

Go to download

jAgg is a Java 5.0 API that supports “group by” operations on Lists of Java objects: aggregate operations such as count, sum, max, min, avg, and many more. It also allows custom aggregate operations.

The newest version!
package net.sf.jagg.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.jagg.AggregateFunction;

/**
 * Created as a wrapper around a Map that maps specification
 * strings to Lists of an implementation of
 * AggregateFunctions.
 *
 * @author Randy Gettman
 * @since 0.9.0
 */
public abstract class FunctionCache
{
   private final Map> myAggregators;

   /**
    * Constructs a FunctionCache.
    */
   public FunctionCache()
   {
      myAggregators = new HashMap>();
   }

   /**
    * Adds the given AggregateFunction to an internal cache.  If
    * it's not in use, then it marks it as "in use" and returns it.  Else, it
    * searches the cache for an AggregateFunction that matches the
    * given AggregateFunction and is not already in use.  If none
    * exist in the cache, then it replicates the given AggregateFunction,
    * adds it to the cache, and returns it.
    *
    * @param archetype The AggregateFunction whose properties (and
    *    type) need to be matched.
    * @return A matching AggregateFunction object.  It could be
    *    archetype itself if it's not already in use, or it could
    *    be null if archetype was null.
    */
   public F getFunction(F archetype)
   {
      if (archetype == null)
         return null;

      List aggsList;
      F agg = null;

//      long time1 = System.nanoTime();

      // Synchronize access to the cache so multiple Threads don't "find"
      // the same AggregateFunction.
      synchronized (myAggregators)
      {
         // Use the given AggregateFunction if it was not already in use.
         // This must be within a synchronized block so that the same archetype
         // is not chosen by multiple threads.  It is in THIS synchronized
         // block to avoid having to get multiple locks.
         if (!archetype.isInUse())
         {
            archetype.setInUse(true);
            agg = archetype;
         }

         // If we can't use the archetype itself...
         if (agg == null)
         {
            aggsList = myAggregators.get(archetype.toString());
            // If we have a list of aggregators matching the name and property.
            if (aggsList != null)
            {
               // Look for one that's not in use.
               int size = aggsList.size();
               for (int a = 0; a < size; a++)
               {
                  F candidate = aggsList.get(a);
                  if (!candidate.isInUse())
                  {
                     agg = candidate;
                     // Set as "in use" before coming out of synchronization.
                     agg.setInUse(true);
                     break;
                  }
               }

            }
            if (aggsList == null)
            {
               aggsList = new ArrayList();
               myAggregators.put(archetype.toString(), aggsList);
            }

            // We must create another AggregateFunction and add it to the cache.
            // Only replicated AggregateFunction are added to the cache; archetypes
            // are not added to the cache.
            if (agg == null)
            {
               //agg = archetype.replicate();
               agg = replicate(archetype);

               // Set as in use before adding to the cache, so another Thread
               // won't pick up this one.
               agg.setInUse(true);
               aggsList.add(agg);
            }
         }
      }
//      long time10 = System.nanoTime();
//      System.out.println("AC timings: All of gA: " + (time10 - time1));
      return agg;
   }

   /**
    * Replicates the given archetype, preserving the same type.
    * @param archetype An archetype to either use or copy.
    * @return The archetype itself, if it's not already in use, or a copy.
    */
   protected abstract F replicate(F archetype);
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy