- more work on generic pools
- generic inlist
This commit is contained in:
parent
ab56cc4b18
commit
129a780c41
@ -16,10 +16,11 @@ package org.oscim.renderer.layer;
|
|||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.utils.pool.Inlist;
|
||||||
/**
|
/**
|
||||||
* @authorHannes Janetzek
|
* @authorHannes Janetzek
|
||||||
*/
|
*/
|
||||||
public abstract class Layer {
|
public abstract class Layer extends Inlist<Layer>{
|
||||||
public final static byte LINE = 0;
|
public final static byte LINE = 0;
|
||||||
public final static byte POLYGON = 1;
|
public final static byte POLYGON = 1;
|
||||||
public final static byte TEXLINE = 2;
|
public final static byte TEXLINE = 2;
|
||||||
@ -31,8 +32,6 @@ public abstract class Layer {
|
|||||||
|
|
||||||
public byte type = -1;
|
public byte type = -1;
|
||||||
|
|
||||||
public Layer next;
|
|
||||||
|
|
||||||
// drawing order from bottom to top
|
// drawing order from bottom to top
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
|
|||||||
@ -43,8 +43,6 @@ public class TextItem extends Inlist<TextItem> {
|
|||||||
|
|
||||||
TextItem ti = pool.get();
|
TextItem ti = pool.get();
|
||||||
|
|
||||||
ti.next = null;
|
|
||||||
|
|
||||||
ti.x = orig.x;
|
ti.x = orig.x;
|
||||||
ti.y = orig.y;
|
ti.y = orig.y;
|
||||||
|
|
||||||
@ -56,6 +54,22 @@ public class TextItem extends Inlist<TextItem> {
|
|||||||
return ti;
|
return ti;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean shareText(TextItem ti1, TextItem ti2){
|
||||||
|
if (ti1.text != ti2.text)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ti1.string == ti2.string)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ti1.string.equals(ti2.string)){
|
||||||
|
// make strings unique, should be done only once..
|
||||||
|
ti1.string = ti2.string;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public TextItem set(float x, float y, String string, Text text) {
|
public TextItem set(float x, float y, String string, Text text) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
|
|||||||
@ -21,11 +21,15 @@ package org.oscim.renderer.overlays;
|
|||||||
// 2. compare previous to current state
|
// 2. compare previous to current state
|
||||||
// 2.1 test for new labels to be placed
|
// 2.1 test for new labels to be placed
|
||||||
// 2.2 handle collisions
|
// 2.2 handle collisions
|
||||||
|
// 2.3 try to place labels along a way
|
||||||
|
// 2.4 use 4 point labeling
|
||||||
// 3 join segments that belong to one feature
|
// 3 join segments that belong to one feature
|
||||||
// 4 handle zoom-level changes
|
// 4 handle zoom-level changes
|
||||||
// 5 R-Tree might be handy
|
// 5 R-Tree might be handy
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.generator.JobTile;
|
||||||
@ -47,6 +51,7 @@ import org.oscim.theme.renderinstruction.Line;
|
|||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.OBB2D;
|
import org.oscim.utils.OBB2D;
|
||||||
import org.oscim.utils.PausableThread;
|
import org.oscim.utils.PausableThread;
|
||||||
|
import org.oscim.utils.pool.LList;
|
||||||
import org.oscim.utils.pool.Pool;
|
import org.oscim.utils.pool.Pool;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
import org.oscim.view.MapViewPosition;
|
import org.oscim.view.MapViewPosition;
|
||||||
@ -72,34 +77,46 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
// TextLayer that is ready to be added to 'layers'
|
// TextLayer that is ready to be added to 'layers'
|
||||||
private TextLayer mNextLayer;
|
private TextLayer mNextLayer;
|
||||||
|
|
||||||
// local pool, avoids synchronized TextItem.get()/release()
|
// thread local pool
|
||||||
|
|
||||||
|
|
||||||
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);
|
TextItem.pool.release(l.item);
|
||||||
|
|
||||||
|
// drop references
|
||||||
l.item = null;
|
l.item = null;
|
||||||
}
|
l.tile = null;
|
||||||
|
l.string = null;
|
||||||
|
|
||||||
Label ret = (Label) l.next;
|
Label ret = (Label) l.next;
|
||||||
|
|
||||||
super.release(l);
|
super.release(l);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TextItem createItem() {
|
||||||
|
return new Label();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LabelPool mPool = new LabelPool();
|
private final LabelPool mPool = new LabelPool();
|
||||||
|
|
||||||
|
// list of previous labels
|
||||||
private Label mPrevLabels;
|
private Label mPrevLabels;
|
||||||
|
|
||||||
|
// list of current labels
|
||||||
private Label mLabels;
|
private Label mLabels;
|
||||||
|
|
||||||
private final float[] mTmpCoords = new float[8];
|
private final float[] mTmpCoords = new float[8];
|
||||||
|
|
||||||
//private HashMap<MapTile, Label> mItemMap;
|
private final HashMap<MapTile, LabelTile> mActiveTiles;
|
||||||
//private Label mNewLabels;
|
|
||||||
//private final HashMap<MapTile, Link> mActiveTiles;
|
class LabelTile {
|
||||||
|
Tile tile;
|
||||||
|
LList<Label> labels;
|
||||||
|
}
|
||||||
|
|
||||||
class Label extends TextItem {
|
class Label extends TextItem {
|
||||||
TextItem item;
|
TextItem item;
|
||||||
@ -141,16 +158,9 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
this.x2 = x + width / 2;
|
this.x2 = x + width / 2;
|
||||||
this.y2 = y + text.fontHeight / 2;
|
this.y2 = y + text.fontHeight / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// class Link {
|
|
||||||
// Link next;
|
|
||||||
// Link prev;
|
|
||||||
// Label it;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// class ActiveTile {
|
// class ActiveTile {
|
||||||
// MapTile tile;
|
// MapTile tile;
|
||||||
// int activeLabels;
|
// int activeLabels;
|
||||||
@ -196,7 +206,7 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
|
|
||||||
layers.textureLayers = new TextLayer();
|
layers.textureLayers = new TextLayer();
|
||||||
mTmpLayer = new TextLayer();
|
mTmpLayer = new TextLayer();
|
||||||
//mActiveTiles = new HashMap<MapTile, Link>();
|
mActiveTiles = new HashMap<MapTile, LabelTile>();
|
||||||
mTmpPos = new MapPosition();
|
mTmpPos = new MapPosition();
|
||||||
mThread = new LabelThread();
|
mThread = new LabelThread();
|
||||||
mThread.start();
|
mThread.start();
|
||||||
@ -207,89 +217,83 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
// remove Label l from mLabels and return l.next
|
// remove Label l from mLabels and return l.next
|
||||||
private Label removeLabel(Label l) {
|
private Label removeLabel(Label l) {
|
||||||
Label ret = (Label) l.next;
|
Label ret = (Label) l.next;
|
||||||
mPool.release(mLabels, l);
|
mLabels = (Label)mPool.release(mLabels, l);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLabel(Label item) {
|
public void addLabel(Label l) {
|
||||||
TextItem it = mLabels;
|
TextItem ll = mLabels;
|
||||||
|
|
||||||
for (; it != null; it = it.next) {
|
for (; ll != null; ll = ll.next) {
|
||||||
|
// find other label with same text style
|
||||||
if (item.text == it.text) {
|
if (l.text == ll.text) {
|
||||||
while (it.next != null
|
while (ll.next != null
|
||||||
// break if next item uses different text style
|
// break if next item uses different text style
|
||||||
&& item.text == it.next.text
|
&& l.text == ll.next.text
|
||||||
// check same string instance
|
// check same string instance
|
||||||
&& item.string != it.string
|
&& l.string != ll.string
|
||||||
// check same string
|
// check same string
|
||||||
&& !item.string.equals(it.string))
|
&& !l.string.equals(ll.string))
|
||||||
it = it.next;
|
ll = ll.next;
|
||||||
|
|
||||||
// unify duplicate string :)
|
|
||||||
// Note: this is required for 'packing test' in prepare to work!
|
// Note: this is required for 'packing test' in prepare to work!
|
||||||
if (item.string != it.string && item.string.equals(it.string))
|
TextItem.shareText(l, ll);
|
||||||
item.string = it.string;
|
|
||||||
|
|
||||||
// insert after text of same type and/or before same string
|
// insert after text of same type and/or before same string
|
||||||
item.next = it.next;
|
l.next = ll.next;
|
||||||
it.next = item;
|
ll.next = l;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item.next = mLabels;
|
l.next = mLabels;
|
||||||
mLabels = item;
|
mLabels = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte checkOverlap(Label ti) {
|
private byte checkOverlap(Label l) {
|
||||||
|
|
||||||
for (Label lp = mLabels; lp != null;) {
|
|
||||||
|
|
||||||
|
for (Label ll = mLabels; ll != null;) {
|
||||||
// check bounding box
|
// check bounding box
|
||||||
if (!TextItem.bboxOverlaps(ti, lp, 150)) {
|
if (!TextItem.bboxOverlaps(l, ll, 150)) {
|
||||||
lp = (Label) lp.next;
|
ll = (Label) ll.next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp.text == ti.text && (lp.string == ti.string || lp.string.equals(ti.string))) {
|
if (TextItem.shareText(l, ll)) {
|
||||||
|
|
||||||
// make strings unique, should be done only once..
|
|
||||||
ti.string = lp.string;
|
|
||||||
|
|
||||||
// keep the label that was active earlier
|
// keep the label that was active earlier
|
||||||
if (lp.active <= ti.active)
|
if (ll.active <= l.active)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// keep the label with longer segment
|
// keep the label with longer segment
|
||||||
if (lp.length < ti.length) {
|
if (ll.length < l.length) {
|
||||||
lp = removeLabel(lp);
|
ll = removeLabel(ll);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean intersect = ti.bbox.overlaps(lp.bbox);
|
boolean intersect = l.bbox.overlaps(ll.bbox);
|
||||||
|
|
||||||
if (intersect) {
|
if (intersect) {
|
||||||
|
if (ll.active <= l.active)
|
||||||
if (lp.active <= ti.active)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
//Log.d(TAG, "intersection " + lp.string + " <> " + ti.string
|
//Log.d(TAG, "intersection " + lp.string + " <> " + ti.string
|
||||||
// + " at " + ti.x + ":" + ti.y);
|
// + " at " + ti.x + ":" + ti.y);
|
||||||
|
|
||||||
if (!lp.text.caption
|
if (!ll.text.caption
|
||||||
&& (lp.text.priority > ti.text.priority || lp.length < ti.length)) {
|
&& (ll.text.priority > l.text.priority || ll.length < l.length)) {
|
||||||
|
|
||||||
lp = removeLabel(lp);
|
ll = removeLabel(ll);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lp = (Label) lp.next;
|
ll = (Label) ll.next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -325,10 +329,6 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
|
|
||||||
private Label getLabel() {
|
private Label getLabel() {
|
||||||
Label l = (Label) mPool.get();
|
Label l = (Label) mPool.get();
|
||||||
|
|
||||||
if (l == null)
|
|
||||||
l = new Label();
|
|
||||||
|
|
||||||
l.active = Integer.MAX_VALUE;
|
l.active = Integer.MAX_VALUE;
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
@ -384,7 +384,6 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
|
|
||||||
int maxx = Tile.SIZE << (zoom - 1);
|
int maxx = Tile.SIZE << (zoom - 1);
|
||||||
|
|
||||||
Label l = null;
|
|
||||||
|
|
||||||
if (dbg != null)
|
if (dbg != null)
|
||||||
addDebugLayers(dbg);
|
addDebugLayers(dbg);
|
||||||
@ -394,7 +393,7 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
double tileX = (pos.x * (Tile.SIZE << zoom));
|
double tileX = (pos.x * (Tile.SIZE << zoom));
|
||||||
double tileY = (pos.y * (Tile.SIZE << zoom));
|
double tileY = (pos.y * (Tile.SIZE << zoom));
|
||||||
|
|
||||||
for (l = mPrevLabels; l != null;) {
|
for (Label l = mPrevLabels; l != null;) {
|
||||||
if (l.text.caption) {
|
if (l.text.caption) {
|
||||||
l = mPool.releaseAndGetNext(l);
|
l = mPool.releaseAndGetNext(l);
|
||||||
continue;
|
continue;
|
||||||
@ -445,20 +444,20 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
addDebugBox(dbg, l, l.item, overlaps, true, sscale);
|
addDebugBox(dbg, l, l.item, overlaps, true, sscale);
|
||||||
|
|
||||||
if (overlaps == 0) {
|
if (overlaps == 0) {
|
||||||
Label tmp = l;
|
Label ll = l;
|
||||||
l = (Label) l.next;
|
l = (Label) l.next;
|
||||||
|
|
||||||
tmp.next = null;
|
ll.next = null;
|
||||||
addLabel(tmp);
|
addLabel(ll);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = mPool.releaseAndGetNext(l);
|
l = mPool.releaseAndGetNext(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label l = null;
|
||||||
|
|
||||||
/* add way labels */
|
/* add way labels */
|
||||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||||
|
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
if (t.state != JobTile.STATE_READY)
|
if (t.state != JobTile.STATE_READY)
|
||||||
continue;
|
continue;
|
||||||
@ -737,11 +736,12 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void render(MapPosition pos, Matrices m) {
|
public synchronized void render(MapPosition pos, Matrices m) {
|
||||||
//float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel);
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, layers.vbo.id);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, layers.vbo.id);
|
||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
|
|
||||||
|
float scale = (float) (mMapPosition.scale / pos.scale);
|
||||||
|
|
||||||
if (layers.baseLayers != null) {
|
if (layers.baseLayers != null) {
|
||||||
setMatrix(pos, m, true);
|
setMatrix(pos, m, true);
|
||||||
|
|
||||||
@ -749,49 +749,18 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
if (l.type == Layer.POLYGON) {
|
if (l.type == Layer.POLYGON) {
|
||||||
l = PolygonRenderer.draw(pos, l, m, true, false);
|
l = PolygonRenderer.draw(pos, l, m, true, false);
|
||||||
} else {
|
} else {
|
||||||
//float scale = pos.getScale() * div;
|
float div = scale * (float) (pos.scale / (1 << pos.zoomLevel));
|
||||||
|
l = LineRenderer.draw(layers, l, pos, m, div, 0);
|
||||||
float scale = (float) ((1 << mMapPosition.zoomLevel) / pos.scale);
|
|
||||||
|
|
||||||
l = LineRenderer.draw(layers, l, pos, m, scale, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setMatrix(pos, m);
|
setMatrix(pos, m, false);
|
||||||
for (Layer l = layers.textureLayers; l != null;) {
|
|
||||||
float scale = (float) (mMapPosition.scale / pos.scale);
|
|
||||||
//float scale = (mMapPosition.getScale() / pos.getScale()) * div;
|
|
||||||
|
|
||||||
|
for (Layer l = layers.textureLayers; l != null;)
|
||||||
l = TextureRenderer.draw(l, scale, m);
|
l = TextureRenderer.draw(l, scale, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setMatrix(MapPosition curPos, Matrices m) {
|
|
||||||
MapPosition oPos = mMapPosition;
|
|
||||||
|
|
||||||
double tileScale = Tile.SIZE * curPos.scale;
|
|
||||||
double scale = (curPos.scale / oPos.scale);
|
|
||||||
|
|
||||||
float x = (float) ((oPos.x - curPos.x) * tileScale);
|
|
||||||
float y = (float) ((oPos.y - curPos.y) * tileScale);
|
|
||||||
|
|
||||||
m.mvp.setTransScale(x, y, (float) (scale / GLRenderer.COORD_SCALE));
|
|
||||||
|
|
||||||
// float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel);
|
|
||||||
// float x = (float) (oPos.x - curPos.x * div);
|
|
||||||
// float y = (float) (oPos.y - curPos.y * div);
|
|
||||||
//
|
|
||||||
// float scale = (curPos.getScale() / oPos.getScale()) / div;
|
|
||||||
// float s = curPos.getScale() / div;
|
|
||||||
// m.mvp.setTransScale(x * s, y * s,
|
|
||||||
// scale / GLRenderer.COORD_SCALE);
|
|
||||||
|
|
||||||
m.mvp.multiplyMM(m.view, m.mvp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean mHolding;
|
private boolean mHolding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -112,8 +112,8 @@ public final class GeometryUtils {
|
|||||||
// The lines are parallel.
|
// The lines are parallel.
|
||||||
// Check if they're collinear.
|
// Check if they're collinear.
|
||||||
double y3LessY1 = y3 - y1;
|
double y3LessY1 = y3 - y1;
|
||||||
double collinearityTestForP3 = x1 * (y2 - y3) + x2 * (y3LessY1) + x3 * (y1 - y2); // see
|
// see http://mathworld.wolfram.com/Collinear.html
|
||||||
// http://mathworld.wolfram.com/Collinear.html
|
double collinearityTestForP3 = x1 * (y2 - y3) + x2 * (y3LessY1) + x3 * (y1 - y2);
|
||||||
// If p3 is collinear with p1 and p2 then p4 will also be collinear,
|
// If p3 is collinear with p1 and p2 then p4 will also be collinear,
|
||||||
// since p1-p2 is parallel with p3-p4
|
// since p1-p2 is parallel with p3-p4
|
||||||
if (collinearityTestForP3 == 0) {
|
if (collinearityTestForP3 == 0) {
|
||||||
|
|||||||
19
src/org/oscim/utils/pool/LList.java
Normal file
19
src/org/oscim/utils/pool/LList.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.utils.pool;
|
||||||
|
|
||||||
|
public class LList<T> extends Inlist<LList<T>> {
|
||||||
|
T data;
|
||||||
|
}
|
||||||
@ -14,26 +14,44 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.utils.pool;
|
package org.oscim.utils.pool;
|
||||||
|
|
||||||
public class Pool<T extends Inlist<T>> {
|
public abstract class Pool<T extends Inlist<T>> {
|
||||||
|
|
||||||
T pool;
|
T pool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param item release resources
|
||||||
|
*/
|
||||||
|
protected void clearItem(T item) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// release 'item' to pool.
|
||||||
|
// make sure that item is not in any other Inlist!
|
||||||
public void release(T item) {
|
public void release(T item) {
|
||||||
if (item == null)
|
if (item == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
clearItem(item);
|
||||||
|
|
||||||
item.next = pool;
|
item.next = pool;
|
||||||
pool = item;
|
pool = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove 'item' from 'list' and add back to pool
|
// remove 'item' from 'list' and add back to pool
|
||||||
public void release(T list, T item) {
|
public T release(T list, T item) {
|
||||||
if (item == null)
|
if (item == null)
|
||||||
return;
|
return list;
|
||||||
|
|
||||||
|
clearItem(item);
|
||||||
|
|
||||||
|
|
||||||
if (item == list) {
|
if (item == list) {
|
||||||
|
T ret = item.next;
|
||||||
|
|
||||||
item.next = pool;
|
item.next = pool;
|
||||||
pool = item;
|
pool = item;
|
||||||
return;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (T prev = list, it = list.next; it != null; it = it.next) {
|
for (T prev = list, it = list.next; it != null; it = it.next) {
|
||||||
@ -43,15 +61,20 @@ public class Pool<T extends Inlist<T>> {
|
|||||||
|
|
||||||
item.next = pool;
|
item.next = pool;
|
||||||
pool = item;
|
pool = item;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
prev = it;
|
prev = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract T createItem();
|
||||||
|
|
||||||
public T get() {
|
public T get() {
|
||||||
|
|
||||||
if (pool == null)
|
if (pool == null)
|
||||||
return null;
|
return createItem();
|
||||||
|
|
||||||
T ret = pool;
|
T ret = pool;
|
||||||
pool = pool.next;
|
pool = pool.next;
|
||||||
|
|||||||
@ -71,6 +71,7 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
if (fill > maxFill)
|
if (fill > maxFill)
|
||||||
while (item != null) {
|
while (item != null) {
|
||||||
clearItem(item);
|
clearItem(item);
|
||||||
|
|
||||||
item = item.next;
|
item = item.next;
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
@ -99,6 +100,8 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
|
|
||||||
T ret = list;
|
T ret = list;
|
||||||
|
|
||||||
|
clearItem(item);
|
||||||
|
|
||||||
if (item == list) {
|
if (item == list) {
|
||||||
ret = item.next;
|
ret = item.next;
|
||||||
} else {
|
} else {
|
||||||
@ -110,8 +113,6 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearItem(item);
|
|
||||||
|
|
||||||
if (fill < maxFill) {
|
if (fill < maxFill) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
fill++;
|
fill++;
|
||||||
@ -127,12 +128,13 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public T get() {
|
public T get() {
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
if (pool == null){
|
if (pool == null){
|
||||||
count++;
|
count++;
|
||||||
return createItem();
|
return createItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
fill--;
|
fill--;
|
||||||
|
|
||||||
T ret = pool;
|
T ret = pool;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user