SyncPool/Pool: allow to pool any subclass of Inlist

This commit is contained in:
Hannes Janetzek 2014-03-18 23:09:28 +01:00
parent 6113d284d8
commit 56a223e6c6
5 changed files with 74 additions and 61 deletions

View File

@ -74,12 +74,12 @@ public class MapRenderer {
} }
public BufferItem get(int size) { public BufferItem get(int size) {
BufferItem b = pool; BufferItem b = mPool;
if (b == null) { if (b == null) {
b = new BufferItem(); b = new BufferItem();
} else { } else {
pool = b.next; mPool = b.next;
b.next = null; b.next = null;
} }
if (b.tmpBufferSize < size) if (b.tmpBufferSize < size)

View File

@ -24,7 +24,7 @@ import org.oscim.utils.pool.SyncPool;
public class SymbolItem extends Inlist<SymbolItem> { public class SymbolItem extends Inlist<SymbolItem> {
public final static SyncPool<SymbolItem> pool = new SyncPool<SymbolItem>() { public final static SyncPool<SymbolItem> pool = new SyncPool<SymbolItem>(128) {
@Override @Override
protected SymbolItem createItem() { protected SymbolItem createItem() {

View File

@ -30,9 +30,11 @@ import javax.annotation.CheckReturnValue;
*/ */
public class Inlist<T extends Inlist<T>> { public class Inlist<T extends Inlist<T>> {
/** UNTESTED */ /** UNTESTED */
public static class List<T extends Inlist<T>> implements Iterable<T> {
T head; @SuppressWarnings({ "rawtypes", "unchecked" })
T cur; public static class List<T extends Inlist<?>> implements Iterable<T> {
Inlist head;
Inlist cur;
Iterator<T> mIterator = new Iterator<T>() { Iterator<T> mIterator = new Iterator<T>() {
@Override @Override
@ -45,14 +47,14 @@ public class Inlist<T extends Inlist<T>> {
if (cur == null) if (cur == null)
throw new IllegalStateException(); throw new IllegalStateException();
T tmp = cur; Inlist tmp = cur;
cur = cur.next; cur = cur.next;
return tmp; return (T) tmp;
} }
@Override @Override
public void remove() { public void remove() {
T tmp = cur.next; T tmp = (T) cur.next;
head = Inlist.remove(head, cur); head = Inlist.remove(head, cur);
cur = tmp; cur = tmp;
} }
@ -65,7 +67,7 @@ public class Inlist<T extends Inlist<T>> {
} }
public void push(T it) { public void push(T it) {
it.next = head; ((Inlist) it).next = head;
head = it; head = it;
} }
@ -75,19 +77,23 @@ public class Inlist<T extends Inlist<T>> {
} }
public T clear() { public T clear() {
T ret = head; Inlist ret = head;
head = null; head = null;
cur = null; cur = null;
return ret; return (T) ret;
} }
public T getHead() { public T getHead() {
return head; return (T) head;
} }
} }
public T next; public T next;
public T next() {
return next;
}
/** /**
* Push 'item' onto 'list'. * Push 'item' onto 'list'.
* *

View File

@ -18,11 +18,11 @@ package org.oscim.utils.pool;
import javax.annotation.CheckReturnValue; import javax.annotation.CheckReturnValue;
public abstract class Pool<T extends Inlist<T>> { @SuppressWarnings({ "rawtypes", "unchecked" })
public abstract class Pool<T extends Inlist<?>> {
protected T pool; protected T mPool;
protected int limit; protected int mLimit;
protected int fill; protected int mFill;
/** /**
* @param item release resources * @param item release resources
@ -47,8 +47,8 @@ public abstract class Pool<T extends Inlist<T>> {
if (!clearItem(item)) if (!clearItem(item))
return null; return null;
item.next = pool; ((Inlist) item).next = mPool;
pool = item; mPool = item;
return null; return null;
} }
@ -65,12 +65,13 @@ public abstract class Pool<T extends Inlist<T>> {
return null; return null;
while (list != null) { while (list != null) {
T next = list.next;
T next = (T) list.next;
clearItem(list); clearItem(list);
list.next = pool; ((Inlist) list).next = mPool;
pool = list; mPool = list;
list = next; list = next;
} }
@ -84,21 +85,21 @@ public abstract class Pool<T extends Inlist<T>> {
clearItem(item); clearItem(item);
Inlist.remove(list, item); Inlist.remove((Inlist) list, item);
return list; return list;
} }
/** get an item from pool */ /** get an item from pool */
public T get() { public T get() {
if (pool == null) if (mPool == null)
return createItem(); return createItem();
T ret = pool; Inlist ret = mPool;
pool = pool.next; mPool = (T) mPool.next;
ret.next = null; ret.next = null;
return ret; return (T) ret;
} }
protected abstract T createItem(); protected abstract T createItem();

View File

@ -18,24 +18,25 @@ package org.oscim.utils.pool;
import javax.annotation.CheckReturnValue; import javax.annotation.CheckReturnValue;
public abstract class SyncPool<T extends Inlist<T>> { public abstract class SyncPool<T extends Inlist<?>> {
protected final int maxFill; protected final int mMaxFill;
protected int fill; protected final boolean mClearItems;
protected T pool; protected int mFill;
protected T mPool;
public SyncPool() {
maxFill = 100;
fill = 0;
}
public SyncPool(int maxItemsInPool) { public SyncPool(int maxItemsInPool) {
maxFill = maxItemsInPool; this(maxItemsInPool, true);
fill = 0; }
public SyncPool(int maxItemsInPool, boolean clearItems) {
mMaxFill = maxItemsInPool;
mFill = 0;
mClearItems = clearItems;
} }
public int getFill() { public int getFill() {
return fill; return mFill;
} }
/** /**
@ -45,8 +46,8 @@ public abstract class SyncPool<T extends Inlist<T>> {
* number of initial items * number of initial items
*/ */
public void init(int items) { public void init(int items) {
fill = 0; mFill = 0;
pool = null; mPool = null;
} }
/** /**
@ -80,24 +81,25 @@ public abstract class SyncPool<T extends Inlist<T>> {
* Usage item = pool.release(item), to ensure to not keep a reference to * Usage item = pool.release(item), to ensure to not keep a reference to
* item! * item!
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" })
@CheckReturnValue @CheckReturnValue
public T release(T item) { public T release(T item) {
if (item == null) if (item == null)
return null; return null;
if (!clearItem(item)) { if (mClearItems && !clearItem(item)) {
// dont add back to pool // dont add back to pool
freeItem(item); freeItem(item);
return null; return null;
} }
if (fill < maxFill) { if (mFill < mMaxFill) {
synchronized (this) { synchronized (this) {
fill++; mFill++;
item.next = pool; ((Inlist) item).next = (T) mPool;
pool = item; mPool = item;
} }
} else { } else if (mClearItems) {
freeItem(item); freeItem(item);
} }
return null; return null;
@ -109,35 +111,38 @@ public abstract class SyncPool<T extends Inlist<T>> {
* Usage list = pool.releaseAll(list), to ensure to not keep a reference to * Usage list = pool.releaseAll(list), to ensure to not keep a reference to
* list! * list!
*/ */
@SuppressWarnings({ "unchecked", "rawtypes" })
@CheckReturnValue @CheckReturnValue
public T releaseAll(T item) { public T releaseAll(T item) {
if (item == null) if (item == null)
return null; return null;
if (fill > maxFill) { if (mFill > mMaxFill) {
while (item != null) { while (item != null) {
clearItem(item); if (mClearItems) {
freeItem(item); clearItem(item);
item = item.next; freeItem(item);
}
item = (T) item.next;
} }
return null; return null;
} }
synchronized (this) { synchronized (this) {
while (item != null) { while (item != null) {
T next = item.next; T next = (T) item.next;
if (!clearItem(item)) { if (mClearItems && !clearItem(item)) {
// dont add back to pool // dont add back to pool
freeItem(item); freeItem(item);
item = next; item = next;
continue; continue;
} }
fill++; mFill++;
item.next = pool; ((Inlist) item).next = (T) mPool;
pool = item; mPool = item;
item = next; item = next;
} }
@ -151,17 +156,18 @@ public abstract class SyncPool<T extends Inlist<T>> {
* *
* @return the item * @return the item
*/ */
@SuppressWarnings("unchecked")
public T get() { public T get() {
synchronized (this) { synchronized (this) {
if (pool == null) { if (mPool == null) {
return createItem(); return createItem();
} }
fill--; mFill--;
T ret = pool; T ret = mPool;
pool = pool.next; mPool = (T) mPool.next;
ret.next = null; ret.next = null;
return ret; return ret;