| /******************************************************************************* |
| * Copyright (c) 1997, 2018 by ProSyst Software GmbH |
| * http://www.prosyst.com |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * ProSyst Software GmbH - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.equinox.internal.util.pool; |
| |
| /** |
| * @author Pavlin Dobrev |
| * @version 1.0 |
| */ |
| |
| public class ObjectPool { |
| |
| private Class<?> template; |
| |
| protected Object[][] buff; |
| |
| protected int nextFree; |
| |
| protected int size; |
| |
| protected int minimumFill; |
| |
| protected int factor; |
| |
| protected int minfSize; |
| |
| protected int minffactor; |
| |
| // protected int usageGet = 0; |
| |
| // protected int usageReleased = 0; |
| |
| protected boolean dontExtend = false; |
| |
| protected ObjectCreator oc; |
| |
| public Object getInstance() throws Exception { |
| return oc != null ? oc.getInstance() : template.newInstance(); |
| } |
| |
| public ObjectPool(ObjectCreator oc, int size, int factor) { |
| this(null, oc, size, factor, size * factor); |
| } |
| |
| public ObjectPool(Class<?> template, int size, int factor) { |
| this(template, null, size, factor, size * factor); |
| } |
| |
| public ObjectPool(Class<?> template, int size, int factor, int minimumFill) { |
| this(template, null, size, factor, (minimumFill = (minimumFill > (size * factor)) ? (size * factor) : minimumFill)); |
| } |
| |
| public ObjectPool(ObjectCreator oc, int size, int factor, int minimumFill) { |
| this(null, oc, size, factor, (minimumFill = minimumFill > (size * factor) ? (size * factor) : minimumFill)); |
| } |
| |
| protected ObjectPool(Class<?> template, ObjectCreator oc, int size, int factor, int minimumFill) { |
| |
| if (size <= 1 || factor < 1) { |
| throw new IllegalArgumentException(size + " is less or equal to 1"); |
| } |
| |
| this.minimumFill = minimumFill < 1 ? 1 : minimumFill; |
| this.oc = oc; |
| if (template != null) { |
| try { |
| template.getConstructor(); |
| this.template = template; |
| } catch (NoSuchMethodException nsm) { |
| throw new IllegalArgumentException(template + " don't have default constructor!"); |
| } |
| } |
| buff = new Object[size][]; |
| this.size = size; |
| this.factor = factor; |
| minfSize = this.minimumFill / factor; |
| minffactor = this.minimumFill % factor; |
| // System.out.println("minimumFill " + this.minimumFill); |
| // System.out.println("minfSize " + minfSize); |
| // System.out.println("minffactor " + minffactor); |
| if (minimumFill <= 1) { |
| nextFree = -1; |
| } else { |
| for (int i = 0; i < (minfSize == 0 ? 1 : minfSize); i++) { |
| buff[i] = new Object[factor]; |
| } |
| fill(); |
| } |
| // start(); |
| } |
| |
| private void fill() { |
| int i = 0; |
| synchronized (buff) { |
| for (; (i < minfSize); i++) { |
| put(i, factor); |
| } |
| if (minffactor > 0) { |
| put(i, minffactor); |
| } |
| } |
| nextFree = minimumFill - 1; |
| } |
| |
| private void put(int i, int count) { |
| for (int j = 0; j < count; j++) { |
| try { |
| if (buff[i] == null) { |
| buff[i] = new Object[factor]; |
| } |
| buff[i][j] = getInstance(); |
| nextFree = i * j; |
| } catch (Throwable t) { |
| throw new RuntimeException("buffer fill failed: " + t); |
| } |
| } |
| } |
| |
| public void clear() { |
| dontExtend = true; |
| shrink(-1); |
| } |
| |
| protected void shrink(int count) { |
| synchronized (buff) { |
| for (; nextFree > count; nextFree--) { |
| buff[(nextFree / factor)][nextFree % factor] = null; |
| } |
| } |
| } |
| |
| public void shrink() { |
| dontExtend = true; |
| shrink(minimumFill); |
| dontExtend = false; |
| } |
| |
| public Object getObject() { |
| Object tmp = null; |
| synchronized (buff) { |
| if (nextFree < 0) { |
| if (dontExtend) { |
| throw new RuntimeException(); |
| } |
| if (minimumFill <= 1) { |
| try { |
| return getInstance(); |
| } catch (Throwable e) { |
| throw new RuntimeException("buffer fill failed: " + e); |
| } |
| } |
| fill(); |
| } |
| tmp = buff[(nextFree / factor)][(nextFree % factor)]; |
| buff[(nextFree / factor)][nextFree % factor] = null; |
| nextFree--; |
| // usageGet++; |
| return tmp; |
| } |
| } |
| |
| public boolean releaseObject(Object obj) { |
| // usageReleased++; |
| if (dontExtend) { |
| return false; |
| } |
| synchronized (buff) { |
| int tmp = nextFree + 1; |
| int telement = tmp / factor; |
| if ((telement) < size) { |
| if (buff[telement] == null) { |
| buff[telement] = new Object[factor]; |
| } |
| buff[telement][tmp % factor] = obj; |
| nextFree = tmp; |
| return true; |
| } |
| return false; |
| } |
| } |
| } |