use @CheckReturnValue for safer pool/Inlist usage

This commit is contained in:
Hannes Janetzek 2013-09-29 05:38:18 +02:00
parent d771d70c3a
commit 5775c8cbf3
18 changed files with 102 additions and 111 deletions

View File

@ -92,7 +92,7 @@ class TextRenderer extends ElementRenderer {
class LabelPool extends Pool<TextItem> { class LabelPool extends Pool<TextItem> {
Label releaseAndGetNext(Label l) { Label releaseAndGetNext(Label l) {
if (l.item != null) if (l.item != null)
TextItem.pool.release(l.item); l.item = TextItem.pool.release(l.item);
// drop references // drop references
l.item = null; l.item = null;
@ -101,6 +101,7 @@ class TextRenderer extends ElementRenderer {
Label ret = (Label) l.next; Label ret = (Label) l.next;
// ignore warning
super.release(l); super.release(l);
return ret; return ret;
@ -561,7 +562,7 @@ class TextRenderer extends ElementRenderer {
} }
// temporary used Label // temporary used Label
mPool.release(l); l = (Label) mPool.release(l);
TextLayer tl = mNextLayer.textLayer; TextLayer tl = mNextLayer.textLayer;
@ -650,8 +651,7 @@ class TextRenderer extends ElementRenderer {
} }
/* private */void cleanup() { /* private */void cleanup() {
mPool.releaseAll(mLabels); mLabels = (Label) mPool.releaseAll(mLabels);
mLabels = null;
mTileSet.releaseTiles(); mTileSet.releaseTiles();
mLabelTask = null; mLabelTask = null;
} }

View File

@ -128,8 +128,7 @@ public class MapRenderer {
} }
public void releaseBuffers() { public void releaseBuffers() {
releaseAll(mUsedBuffers); mUsedBuffers = releaseAll(mUsedBuffers);
mUsedBuffers = null;
} }
} }

View File

@ -66,7 +66,7 @@ public abstract class SpriteManager<T> {
} }
public void clear() { public void clear() {
TextureItem.releaseAll(mTexture); mTexture = TextureItem.pool.releaseAll(mTexture);
mAtlas.clear(); mAtlas.clear();
items = null; items = null;

View File

@ -146,8 +146,7 @@ public class BitmapLayer extends TextureLayer {
TextureItem.releaseTexture(textures); TextureItem.releaseTexture(textures);
textures = null; textures = null;
VertexItem.pool.releaseAll(vertexItems); vertexItems = VertexItem.pool.releaseAll(vertexItems);
vertexItems = null;
} }
public static final class Renderer { public static final class Renderer {

View File

@ -295,7 +295,7 @@ public class ElementLayers {
l.vertexItems = null; l.vertexItems = null;
l.curItem = null; l.curItem = null;
} }
VertexItem.pool.releaseAll(items); items = VertexItem.pool.releaseAll(items);
return size; return size;
} }
@ -311,8 +311,7 @@ public class ElementLayers {
sbuf.put(it.vertices, 0, VertexItem.SIZE); sbuf.put(it.vertices, 0, VertexItem.SIZE);
} }
VertexItem.pool.releaseAll(l.vertexItems); l.vertexItems = VertexItem.pool.releaseAll(l.vertexItems);
l.vertexItems = null;
} }
// cleanup only when layers are not used by tile or overlay anymore! // cleanup only when layers are not used by tile or overlay anymore!
@ -321,8 +320,7 @@ public class ElementLayers {
// clear line and polygon layers directly // clear line and polygon layers directly
for (RenderElement l = baseLayers; l != null; l = l.next) { for (RenderElement l = baseLayers; l != null; l = l.next) {
if (l.vertexItems != null) { if (l.vertexItems != null) {
VertexItem.pool.releaseAll(l.vertexItems); l.vertexItems = VertexItem.pool.releaseAll(l.vertexItems);
l.vertexItems = null;
l.curItem = null; l.curItem = null;
} }
l.verticesCnt = 0; l.verticesCnt = 0;

View File

@ -401,16 +401,10 @@ public class ExtrusionLayer extends RenderElement {
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0); GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
for (int i = 0; i < 4; i++) clear();
VertexItem.pool.releaseAll(mIndices[i]);
VertexItem.pool.releaseAll(mVertices);
mIndices = null;
mVertices = null;
mClipper = null;
compiled = true; compiled = true;
mClipper = null;
} }
@Override @Override
@ -420,11 +414,10 @@ public class ExtrusionLayer extends RenderElement {
vboVertices = BufferObject.release(vboVertices); vboVertices = BufferObject.release(vboVertices);
} else { } else {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
VertexItem.pool.releaseAll(mIndices[i]); mIndices[i] = VertexItem.pool.releaseAll(mIndices[i]);
mIndices = null; mIndices = null;
VertexItem.pool.releaseAll(mVertices); mVertices = VertexItem.pool.releaseAll(mVertices);
mVertices = null;
} }
} }
} }

View File

@ -23,9 +23,9 @@ import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.GLState;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.renderinstruction.Line; import org.oscim.theme.renderinstruction.Line;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
@ -567,8 +567,7 @@ public final class LineLayer extends RenderElement {
@Override @Override
public void clear() { public void clear() {
if (vertexItems != null) { if (vertexItems != null) {
VertexItem.pool.releaseAll(vertexItems); vertexItems = VertexItem.pool.releaseAll(vertexItems);
vertexItems = null;
curItem = null; curItem = null;
} }
verticesCnt = 0; verticesCnt = 0;

View File

@ -62,11 +62,8 @@ public class MeshLayer extends RenderElement {
Log.d(TAG, "-> " + verticesCnt + " " + numIndices); Log.d(TAG, "-> " + verticesCnt + " " + numIndices);
if (numIndices <= 0) { if (numIndices <= 0) {
vertexItems.release(); vertexItems = VertexItem.pool.releaseAll(vertexItems);
vertexItems = null; indiceItems = VertexItem.pool.releaseAll(indiceItems);
indiceItems.release();
indiceItems = null;
} }
} }
@ -95,8 +92,7 @@ public class MeshLayer extends RenderElement {
for (VertexItem it = indiceItems; it != null; it = it.next) for (VertexItem it = indiceItems; it != null; it = it.next)
sbuf.put(it.vertices, 0, it.used); sbuf.put(it.vertices, 0, it.used);
VertexItem.pool.releaseAll(indiceItems); indiceItems = VertexItem.pool.releaseAll(indiceItems);
indiceItems = null;
sbuf.flip(); sbuf.flip();
@ -109,11 +105,8 @@ public class MeshLayer extends RenderElement {
@Override @Override
protected void clear() { protected void clear() {
indicesVbo = BufferObject.release(indicesVbo); indicesVbo = BufferObject.release(indicesVbo);
VertexItem.pool.releaseAll(indiceItems); indiceItems = VertexItem.pool.releaseAll(indiceItems);
VertexItem.pool.releaseAll(vertexItems); vertexItems = VertexItem.pool.releaseAll(vertexItems);
indiceItems = null;
vertexItems = null;
} }
public static class Renderer { public static class Renderer {

View File

@ -174,10 +174,9 @@ public final class SymbolLayer extends TextureLayer {
if (pos > 0) if (pos > 0)
sbuf.put(buf, 0, pos); sbuf.put(buf, 0, pos);
VertexItem.pool.release(si); si = VertexItem.pool.release(si);
TextureItem.releaseAll(prevTextures); prevTextures = TextureItem.pool.releaseAll(prevTextures);
prevTextures = null;
} }
private TextureItem getTexture(Bitmap bitmap) { private TextureItem getTexture(Bitmap bitmap) {
@ -195,19 +194,16 @@ public final class SymbolLayer extends TextureLayer {
} }
public void clearItems() { public void clearItems() {
SymbolItem.pool.releaseAll(symbols); symbols = SymbolItem.pool.releaseAll(symbols);
symbols = null;
verticesCnt = 0; verticesCnt = 0;
} }
@Override @Override
public void clear() { public void clear() {
TextureItem.releaseAll(textures); textures = TextureItem.pool.releaseAll(textures);
SymbolItem.pool.releaseAll(symbols); symbols = SymbolItem.pool.releaseAll(symbols);
vertexItems = VertexItem.pool.releaseAll(vertexItems);
textures = null;
symbols = null;
vertexItems = null;
verticesCnt = 0; verticesCnt = 0;
} }

View File

@ -268,18 +268,13 @@ public final class TextLayer extends TextureLayer {
@Override @Override
public void clear() { public void clear() {
TextureItem.releaseAll(textures); textures = TextureItem.pool.releaseAll(textures);
labels = null; labels = TextItem.pool.releaseAll(labels);
vertexItems = VertexItem.pool.releaseAll(vertexItems);
TextItem.pool.releaseAll(labels);
VertexItem.pool.releaseAll(vertexItems);
textures = null;
vertexItems = null;
verticesCnt = 0; verticesCnt = 0;
} }
public void clearLabels() { public void clearLabels() {
TextItem.pool.releaseAll(labels); labels = TextItem.pool.releaseAll(labels);
labels = null;
} }
} }

View File

@ -105,10 +105,6 @@ public class TextureItem extends Inlist<TextureItem> {
} }
} }
public synchronized static void releaseAll(TextureItem ti) {
pool.releaseAll(ti);
}
/** /**
* Retrieve a TextureItem from pool with default Bitmap with dimension * Retrieve a TextureItem from pool with default Bitmap with dimension
* TextureRenderer.TEXTURE_WIDTH/HEIGHT. * TextureRenderer.TEXTURE_WIDTH/HEIGHT.
@ -191,7 +187,7 @@ public class TextureItem extends Inlist<TextureItem> {
} }
}; };
private final static SyncPool<TextureItem> pool = new TextureItemPool(); public final static SyncPool<TextureItem> pool = new TextureItemPool();
private final static ArrayList<Integer> mTextures = new ArrayList<Integer>(); private final static ArrayList<Integer> mTextures = new ArrayList<Integer>();
private final static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10); private final static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);

View File

@ -35,17 +35,6 @@ public class VertexItem extends Inlist<VertexItem> {
} }
}; };
/**
* Add VertexItems back to pool. Make sure to not use the reference
* afterwards!
* i.e.:
* vertexItem.release();
* vertexItem = null;
* */
public void release() {
VertexItem.pool.releaseAll(this);
}
public int getSize() { public int getSize() {
int size = used; int size = used;
for (VertexItem it = next; it != null; it = it.next) for (VertexItem it = next; it != null; it = it.next)

View File

@ -106,7 +106,7 @@ public class AtlasRenderLayer extends ElementRenderer {
} }
tl.prepare(); tl.prepare();
TextItem.pool.releaseAll(tl.labels); tl.labels = TextItem.pool.releaseAll(tl.labels);
} }
boolean initial = true; boolean initial = true;

View File

@ -225,14 +225,11 @@ public class MapTile extends Tile {
// TODO move this to layers clear // TODO move this to layers clear
layers.vbo = BufferObject.release(layers.vbo); layers.vbo = BufferObject.release(layers.vbo);
layers.clear(); layers.clear();
layers = null;
} }
TextItem.pool.releaseAll(labels); labels = TextItem.pool.releaseAll(labels);
SymbolItem.pool.releaseAll(symbols); symbols = SymbolItem.pool.releaseAll(symbols);
layers = null;
labels = null;
symbols = null;
state = STATE_NONE; state = STATE_NONE;
} }

View File

@ -18,6 +18,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import org.oscim.backend.Log;
import org.oscim.core.GeometryBuffer.GeometryType; import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement; import org.oscim.core.MapElement;
import org.oscim.core.Tag; import org.oscim.core.Tag;
@ -27,8 +28,6 @@ import org.oscim.tiling.source.common.PbfDecoder;
import org.oscim.utils.pool.Inlist; import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.Pool; import org.oscim.utils.pool.Pool;
import org.oscim.backend.Log;
public class TileDecoder extends PbfDecoder { public class TileDecoder extends PbfDecoder {
private final static String TAG = TileDecoder.class.getName(); private final static String TAG = TileDecoder.class.getName();
@ -236,7 +235,7 @@ public class TileDecoder extends PbfDecoder {
// FIXME extract layer tag here // FIXME extract layer tag here
f.elem.setLayer(5); f.elem.setLayer(5);
mMapDataCallback.process(f.elem); mMapDataCallback.process(f.elem);
mFeaturePool.release(f); f = mFeaturePool.release(f);
} }
return true; return true;

View File

@ -14,6 +14,8 @@
*/ */
package org.oscim.utils.pool; package org.oscim.utils.pool;
import javax.annotation.CheckReturnValue;
/** /**
* Utility class for making poolable objects. * Utility class for making poolable objects.
* Instead of using an additional list to hold pool items just extend this * Instead of using an additional list to hold pool items just extend this
@ -33,6 +35,7 @@ public class Inlist<T extends Inlist<T>> {
* @param item the item * @param item the item
* @return the new head of 'list' (item) * @return the new head of 'list' (item)
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T push(T list, T item) { public static <T extends Inlist<T>> T push(T list, T item) {
item.next = list; item.next = list;
return item; return item;
@ -58,6 +61,7 @@ public class Inlist<T extends Inlist<T>> {
* @param item the item * @param item the item
* @return the new head of 'list' * @return the new head of 'list'
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T remove(T list, T item) { public static <T extends Inlist<T>> T remove(T list, T item) {
if (item == list) { if (item == list) {
T head = item.next; T head = item.next;
@ -84,6 +88,7 @@ public class Inlist<T extends Inlist<T>> {
* @param i the index * @param i the index
* @return the item or null * @return the item or null
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T get(T list, int i) { public static <T extends Inlist<T>> T get(T list, int i) {
if (i < 0) if (i < 0)
return null; return null;
@ -105,6 +110,7 @@ public class Inlist<T extends Inlist<T>> {
* @param item the item * @param item the item
* @return the new head of 'list' * @return the new head of 'list'
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T appendItem(T list, T item) { public static <T extends Inlist<T>> T appendItem(T list, T item) {
if (item.next != null) if (item.next != null)
@ -130,6 +136,7 @@ public class Inlist<T extends Inlist<T>> {
* @param other the other * @param other the other
* @return the head of 'list' * @return the head of 'list'
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T appendList(T list, T other) { public static <T extends Inlist<T>> T appendList(T list, T other) {
if (list == null) if (list == null)
@ -157,6 +164,7 @@ public class Inlist<T extends Inlist<T>> {
* @param list the list * @param list the list
* @return the last item * @return the last item
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T last(T list) { public static <T extends Inlist<T>> T last(T list) {
while (list != null) { while (list != null) {
if (list.next == null) if (list.next == null)
@ -174,6 +182,7 @@ public class Inlist<T extends Inlist<T>> {
* @param other the other list * @param other the other list
* @return the new head of list * @return the new head of list
*/ */
@CheckReturnValue
public static <T extends Inlist<T>> T prependRelative(T list, T item, T other) { public static <T extends Inlist<T>> T prependRelative(T list, T item, T other) {
if (item.next != null) if (item.next != null)

View File

@ -14,6 +14,8 @@
*/ */
package org.oscim.utils.pool; package org.oscim.utils.pool;
import javax.annotation.CheckReturnValue;
public abstract class Pool<T extends Inlist<T>> { public abstract class Pool<T extends Inlist<T>> {
protected T pool; protected T pool;
@ -27,33 +29,48 @@ public abstract class Pool<T extends Inlist<T>> {
return true; return true;
} }
// release 'item' to pool. /**
// make sure that item is not in any other Inlist! * Release 'item' to pool.
public void release(T item) { * <p>
* Usage item = pool.release(item), to ensure to not keep a reference to
* item!
*/
@CheckReturnValue
public T release(T item) {
if (item == null) if (item == null)
return; return null;
if (!clearItem(item)) if (!clearItem(item))
return; return null;
item.next = pool;
pool = item;
}
public void releaseAll(T item) {
if (item == null)
return;
while (item != null) {
T next = item.next;
clearItem(item);
item.next = pool; item.next = pool;
pool = item; pool = item;
item = next; return null;
} }
/**
* Release 'list' to pool.
* <p>
* Usage list = pool.releaseAll(list), to ensure to not keep a reference to
* list!
*/
@CheckReturnValue
public T releaseAll(T list) {
if (list == null)
return null;
while (list != null) {
T next = list.next;
clearItem(list);
list.next = pool;
pool = list;
list = next;
}
return null;
} }
// remove 'item' from 'list' and add back to pool // remove 'item' from 'list' and add back to pool

View File

@ -14,6 +14,8 @@
*/ */
package org.oscim.utils.pool; package org.oscim.utils.pool;
import javax.annotation.CheckReturnValue;
public abstract class SyncPool<T extends Inlist<T>> { public abstract class SyncPool<T extends Inlist<T>> {
protected final int maxFill; protected final int maxFill;
protected int fill; protected int fill;
@ -66,14 +68,21 @@ public abstract class SyncPool<T extends Inlist<T>> {
*/ */
protected abstract T createItem(); protected abstract T createItem();
public void release(T item) { /**
* Release 'item' to pool.
* <p>
* Usage item = pool.release(item), to ensure to not keep a reference to
* item!
*/
@CheckReturnValue
public T release(T item) {
if (item == null) if (item == null)
return; return null;
if (!clearItem(item)) { if (!clearItem(item)) {
// dont add back to pool // dont add back to pool
freeItem(item); freeItem(item);
return; return null;
} }
if (fill < maxFill) { if (fill < maxFill) {
synchronized (this) { synchronized (this) {
@ -85,17 +94,19 @@ public abstract class SyncPool<T extends Inlist<T>> {
} else { } else {
freeItem(item); freeItem(item);
} }
return null;
} }
/** /**
* Release all items from 'item'. Do not use the * Release 'list' to pool.
* 'item' reference afterwards! * <p>
* * Usage list = pool.releaseAll(list), to ensure to not keep a reference to
* @param item the item (or list or items) * list!
*/ */
public void releaseAll(T item) { @CheckReturnValue
public T releaseAll(T item) {
if (item == null) if (item == null)
return; return null;
if (fill > maxFill) { if (fill > maxFill) {
while (item != null) { while (item != null) {
@ -103,7 +114,7 @@ public abstract class SyncPool<T extends Inlist<T>> {
freeItem(item); freeItem(item);
item = item.next; item = item.next;
} }
return; return null;
} }
synchronized (this) { synchronized (this) {
@ -125,6 +136,7 @@ public abstract class SyncPool<T extends Inlist<T>> {
item = next; item = next;
} }
} }
return null;
} }
/** /**