X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cadi%2Fcore%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fcadi%2Futil%2FPool.java;h=6980e0aad44dfafb768711f1aad9cea905dc8ca9;hb=ea095eb9cdbb451f2310a262f3877c79f527cc8f;hp=72d09bfe462a5dc7868412d27e2044a697e0c7de;hpb=1296352d8eafee57f982a4342ad79ada4aa56d28;p=aaf%2Fauthz.git diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java index 72d09bfe..6980e0aa 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java @@ -65,7 +65,12 @@ public class Pool { * This is a constant which specified the default maximum number of unused * objects to be held at any given time. */ - private static final int MAX_RANGE = 6; // safety + public static final int MAX_RANGE = 6; // safety + + /** + * Maximum objects, in use or waiting + */ + public static final int MAX_OBJECTS = 20; // assumption for thread /** * only Simple List needed. @@ -76,21 +81,30 @@ public class Pool { private LinkedList> list; /** - * keep track of how many elements exist, to avoid asking list. + * keep track of how many elements are currently available to use, to avoid asking list. */ private int count; - + /** - * Spares are those Object that are primed and ready to go. + * how many objects have been asked for, but not returned or tossed */ - private int spares; - + private int used; + /** * Actual MAX number of spares allowed to hang around. Can be set to * something besides the default MAX_RANGE. */ private int max_range = MAX_RANGE; + /** + * Actual MAX number of Objects both in use, or waiting. + * This does not actually affect the Pool, because the objects, once they leave the pool, are not known until + * they are put back with done (offer). It only affects the "overLimit()" function. + * + * Important... this information is only valid if PooledObjects call "done()" or "toss()". + */ + private int max_objects = MAX_OBJECTS; + /** * The Creator for this particular pool. It must work for type T. */ @@ -105,7 +119,7 @@ public class Pool { * @param creator */ public Pool(Creator creator) { - count = spares = 0; + count = used = 0; this.creator = creator; list = new LinkedList<>(); logger = Log.NULL; @@ -117,29 +131,44 @@ public class Pool { */ public void setLogger(Log logger) { this.logger = logger; + // Also reset existing Pooled objects + for(Pooled p : list) { + if(p.content instanceof LogAware) { + ((LogAware)p.content).setLog(logger); + } else { + break; + } + } } - public void log(Object ...objects) { - logger.log(objects); + public void log(Log.Type type, Object ...objects) { + logger.log(type,objects); } /** * Preallocate a certain number of T Objects. Useful for services so that * the first transactions don't get hit with all the Object creation costs - * + * + * It is assumed that priming also means that it is the minimum desired available resources. Therefore, + * max_range is set to prime, if less than current max_range, if it is default. + * * @param lt * @param prime * @throws CadiException */ - public void prime(int prime) throws CadiException { + public Pool prime(int prime) throws CadiException { + if(max_range == MAX_RANGE && prime pt = new Pooled(creator.create(), this); synchronized (list) { list.addFirst(pt); ++count; + ++used; } } - + return this; } /** @@ -147,19 +176,22 @@ public class Pool { * down all Allocated objects cleanly for exiting. It is also a good method * for removing objects when, for instance, all Objects are invalid because * of broken connections, etc. + * + * Use in conjunction with setMaxRange to no longer store objects, i.e. + * + * pool.setMaxRange(0).drain(); */ - public void drain() { - synchronized (list) { - for (int i = 0; i < list.size(); ++i) { - Pooled pt = list.remove(); - creator.destroy(pt.content); - logger.log("Pool drained ", creator.toString()); - } - count = spares = 0; - } - + public synchronized void drain() { + while(list.size()>0) { + Pooled pt = list.remove(); + --used; + String name = pt.content.toString(); + creator.destroy(pt.content); + logger.log(Log.Type.debug,"Pool destroyed", name); + } + count = 0; } - + /** * This is the essential function for Pool. Get an Object "T" inside a * "Pooled" object. If there is a spare Object, then use it. If not, then @@ -181,21 +213,14 @@ public class Pool { public Pooled get() throws CadiException { Pooled pt; synchronized (list) { - if (list.isEmpty()) { - pt = null; - } else { - pt = list.removeLast(); - --count; - creator.reuse(pt.content); - } + pt = list.pollLast(); } if (pt == null) { - if (spares < max_range) - ++spares; pt = new Pooled(creator.create(), this); + ++used; } else { - if (spares > 1) - --spares; + --count; + creator.reuse(pt.content); } return pt; } @@ -235,19 +260,31 @@ public class Pool { * @return */ // Used only by Pooled - private boolean offer(Pooled used) { - if (count < spares) { + private boolean offer(Pooled usedP) { + if (count < max_range) { synchronized (list) { - list.addFirst(used); + list.addFirst(usedP); ++count; } - logger.log("Pool recovered ", creator); + logger.log(Log.Type.trace,"Pool recovered ", creator); } else { - logger.log("Pool destroyed ", creator); - creator.destroy(used.content); + destroy(usedP.content); } return false; } + + /** + * Destroy, using Creator's specific semantics, the Object, and decrement "used" + * + * @param t + */ + private void destroy(T t) { + creator.destroy(t); + synchronized (list) { + --used; + } + logger.log(Log.Type.debug,"Pool destroyed ", creator); + } /** * The Creator Interface give the Pool the ability to Create, Destroy and @@ -268,15 +305,17 @@ public class Pool { public void reuse(T t); } - public interface Log { - public void log(Object ... o); - - public final static Log NULL = new Log() { - @Override - public void log(Object ... o) { - } - }; + /** + * Pooled Classes can be "Log Aware", which means they can tie into the same + * Logging element that the Pool is using. To do this, the Object must implement "LogAware" + * + * @author Jonathan + * + */ + public interface LogAware { + public void setLog(Log log); } + /** * The "Pooled" class is the transient class that wraps the actual Object * T for API use/ It gives the ability to return ("done()", or "toss()") the @@ -309,8 +348,10 @@ public class Pool { */ public Pooled(T t, Pool pool) { content = t; + if(t instanceof LogAware) { + ((LogAware)t).setLog(pool.logger); + } this.pool = pool; - } /** @@ -338,7 +379,7 @@ public class Pool { */ public void toss() { if (pool != null) { - pool.creator.destroy(content); + pool.destroy(content); } // Don't allow finalize to put it back in. pool = null; @@ -356,17 +397,30 @@ public class Pool { pool = null; } } + + @Override + public String toString() { + return content.toString(); + } } /** - * Get the maximum number of spare objects allowed at any moment + * Set a Max Range for numbers of spare objects waiting to be used. + * + * No negative numbers are allowed + * + * Use in conjunction with drain to no longer store objects, i.e. + * + * pool.setMaxRange(0).drain(); * * @return */ - public int getMaxRange() { - return max_range; + public Pool setMaxRange(int max_range) { + // Do not allow negative numbers + this.max_range = Math.max(0, max_range); + return this; } - + /** * Set a Max Range for numbers of spare objects waiting to be used. * @@ -374,9 +428,26 @@ public class Pool { * * @return */ - public void setMaxRange(int max_range) { + public Pool setMaxObjects(int max_objects) { // Do not allow negative numbers - this.max_range = Math.max(0, max_range); + this.max_objects = Math.max(0, max_objects); + return this; } + /** + * return whether objects in use or waiting are beyond max allowed + * + * Pool does not actually stop new creations, but allows this to be used by + * other entities to limit number of creations of expensive Objects, like + * Thread Pooling + * + */ + public boolean tooManyObjects() { + return used > max_objects; + } + + public String toString() { + return String.format("Pool: count(%d), used(%d), max_range(%d), max_objects(%d)", + count, used,max_range,max_objects); + } }