Skip to content

Commit 27e5d87

Browse files
committed
Replace long[] arrays by a TileIndex abstraction
Dealing with `long[]` everywhere and knowing it means `{x,y,z}` is tiring. Introducing a `TileIndex` abstraction improves the semantics, and at the same time allows to save memory on TileObject by storing the coordinates as internal long,long,int fields and saving the object reference to a `long` array. --- > This is a **proposal**. Can we please stop using `long[]` everywhere? > If accepted, there would be more places to get rid of `long` arrays > and introduce higher level abstractions (e.g. `TileRangeInterator`)
1 parent 0d2fc0b commit 27e5d87

File tree

46 files changed

+481
-278
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+481
-278
lines changed

geowebcache/arcgiscache/src/main/java/org/geowebcache/arcgis/layer/ArcGISCacheLayer.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.geowebcache.layer.ExpirationRule;
5252
import org.geowebcache.mime.MimeException;
5353
import org.geowebcache.mime.MimeType;
54+
import org.geowebcache.storage.TileIndex;
5455
import org.geowebcache.util.GWCVars;
5556

5657
/**
@@ -268,18 +269,18 @@ public ConveyorTile getTile(final ConveyorTile tile)
268269

269270
if (storageFormat.equals(CacheStorageInfo.COMPACT_FORMAT_CODE)
270271
|| storageFormat.equals(CacheStorageInfo.COMPACT_FORMAT_CODE_V2)) {
271-
final long[] tileIndex = tile.getTileIndex();
272+
final TileIndex tileIndex = tile.getIndex();
272273
final String gridSetId = tile.getGridSetId();
273274
final GridSubset gridSubset = this.getGridSubset(gridSetId);
274275

275276
GridSet gridSet = gridSubset.getGridSet();
276-
final int zoom = (int) tileIndex[2];
277+
final int zoom = tileIndex.getZ();
277278

278279
Grid grid = gridSet.getGrid(zoom);
279280
long coverageMaxY = grid.getNumTilesHigh() - 1;
280281

281-
final int col = (int) tileIndex[0];
282-
final int row = (int) (coverageMaxY - tileIndex[1]);
282+
final int col = (int) tileIndex.getX();
283+
final int row = (int) (coverageMaxY - tileIndex.getY());
283284

284285
tileContent = compactCache.getBundleFileResource(zoom, row, col);
285286

@@ -298,7 +299,7 @@ public ConveyorTile getTile(final ConveyorTile tile)
298299
} else {
299300
tile.setCacheResult(CacheResult.MISS);
300301
if (!setLayerBlankTile(tile)) {
301-
throw new OutsideCoverageException(tile.getTileIndex(), 0, 0);
302+
throw new OutsideCoverageException(tile.getIndex().getZ(), 0, 0);
302303
}
303304
}
304305

@@ -370,23 +371,23 @@ private boolean setLayerBlankTile(ConveyorTile tile) {
370371
private String getTilePath(final ConveyorTile tile) {
371372

372373
final MimeType mimeType = tile.getMimeType();
373-
final long[] tileIndex = tile.getTileIndex();
374+
final TileIndex tileIndex = tile.getIndex();
374375
final String gridSetId = tile.getGridSetId();
375376
final GridSubset gridSubset = this.getGridSubset(gridSetId);
376377

377378
GridSet gridSet = gridSubset.getGridSet();
378-
final int z = (int) tileIndex[2];
379+
final int z = tileIndex.getZ();
379380

380381
Grid grid = gridSet.getGrid(z);
381382

382383
// long[] coverage = gridSubset.getCoverage(z);
383384
// long coverageMinY = coverage[1];
384385
long coverageMaxY = grid.getNumTilesHigh() - 1;
385386

386-
final long x = tileIndex[0];
387+
final long x = tileIndex.getX();
387388
// invert the order of the requested Y ordinate, since ArcGIS caches are top-left to
388389
// bottom-right, and GWC computes tiles in bottom-left to top-right order
389-
final long y = (coverageMaxY - tileIndex[1]);
390+
final long y = (coverageMaxY - tileIndex.getY());
390391

391392
String level = (this.hexZoom) ? Integer.toHexString(z) : Integer.toString(z);
392393
level = zeroPadder(level, 2);

geowebcache/core/src/main/java/org/geowebcache/conveyor/ConveyorTile.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.geowebcache.mime.MimeType;
2929
import org.geowebcache.storage.StorageBroker;
3030
import org.geowebcache.storage.StorageException;
31+
import org.geowebcache.storage.TileIndex;
3132
import org.geowebcache.storage.TileObject;
3233

3334
/** Represents a request for a tile and carries the information needed to complete it. */
@@ -72,7 +73,7 @@ public ConveyorTile(
7273
StorageBroker sb,
7374
String layerId,
7475
String gridSetId,
75-
long[] tileIndex,
76+
TileIndex tileIndex,
7677
MimeType mimeType,
7778
Map<String, String[]> fullParameters,
7879
Map<String, String> filteringParameters,
@@ -95,7 +96,7 @@ public ConveyorTile(
9596
StorageBroker sb,
9697
String layerId,
9798
String gridSetId,
98-
long[] tileIndex,
99+
TileIndex tileIndex,
99100
MimeType mimeType,
100101
Map<String, String> filteringParameters,
101102
HttpServletRequest servletReq,
@@ -104,18 +105,11 @@ public ConveyorTile(
104105
super(layerId, sb, servletReq, servletResp);
105106
this.gridSetId = gridSetId;
106107

107-
long[] idx = new long[3];
108-
109-
if (tileIndex != null) {
110-
idx[0] = tileIndex[0];
111-
idx[1] = tileIndex[1];
112-
idx[2] = tileIndex[2];
113-
}
114-
115108
super.mimeType = mimeType;
116109

117110
this.filteringParameters = filteringParameters;
118111

112+
TileIndex idx = tileIndex == null ? null : TileIndex.copyOf(tileIndex);
119113
stObj =
120114
TileObject.createQueryTileObject(
121115
layerId, idx, gridSetId, mimeType.getFormat(), filteringParameters);
@@ -180,6 +174,10 @@ public long[] getTileIndex() {
180174
return stObj.getXYZ();
181175
}
182176

177+
public TileIndex getIndex() {
178+
return stObj.getIndex();
179+
}
180+
183181
public synchronized GridSubset getGridSubset() {
184182
if (gridSubset == null && gridSetId != null) {
185183
gridSubset = tileLayer.getGridSubset(gridSetId);
@@ -248,7 +246,6 @@ public boolean retrieve(long maxAge) throws GeoWebCacheException {
248246
public String toString() {
249247
StringBuilder str = new StringBuilder();
250248
str.append("ConveyorTile[");
251-
long[] idx = stObj.getXYZ();
252249

253250
if (getLayerId() != null) {
254251
str.append(getLayerId()).append(" ");
@@ -258,9 +255,7 @@ public String toString() {
258255
str.append(gridSetId).append(" ");
259256
}
260257

261-
if (idx != null && idx.length == 3) {
262-
str.append("{" + idx[0] + "," + idx[1] + "," + idx[2] + "} ");
263-
}
258+
str.append("{" + stObj.getX() + "," + stObj.getY() + "," + stObj.getZ() + "} ");
264259

265260
if (this.mimeType != null) {
266261
str.append(this.mimeType.getFormat());

geowebcache/core/src/main/java/org/geowebcache/filter/request/CircularExtentFilter.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.geowebcache.conveyor.ConveyorTile;
1919
import org.geowebcache.grid.GridSubset;
2020
import org.geowebcache.layer.TileLayer;
21+
import org.geowebcache.storage.TileIndex;
2122

2223
/**
2324
* This is a test filter for the new request filter core.
@@ -38,7 +39,8 @@ public void apply(ConveyorTile convTile) throws RequestFilterException {
3839
// SRS srs = convTile.getSRS();
3940
GridSubset gridSubset = tl.getGridSubset(convTile.getGridSetId());
4041

41-
int z = (int) convTile.getTileIndex()[2];
42+
TileIndex tileIndex = convTile.getIndex();
43+
int z = tileIndex.getZ();
4244
long[] gridCoverage = gridSubset.getCoverage(z);
4345

4446
// Figure out the radius
@@ -58,8 +60,8 @@ public void apply(ConveyorTile convTile) throws RequestFilterException {
5860
long midX = gridCoverage[0] + width / 2;
5961
long midY = gridCoverage[1] + height / 2;
6062

61-
long xDist = midX - convTile.getTileIndex()[0];
62-
long yDist = midY - convTile.getTileIndex()[1];
63+
long xDist = midX - tileIndex.getX();
64+
long yDist = midY - tileIndex.getY();
6365

6466
long rad = Math.round(Math.sqrt(xDist * xDist + yDist * yDist));
6567

geowebcache/core/src/main/java/org/geowebcache/filter/request/RasterFilter.java

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.geowebcache.grid.GridSubset;
2727
import org.geowebcache.grid.OutsideCoverageException;
2828
import org.geowebcache.layer.TileLayer;
29+
import org.geowebcache.storage.TileIndex;
2930

3031
/**
3132
* A raster filter allows to optimize data loading by avoiding the generation of requests and the
@@ -109,51 +110,54 @@ public void setDebug(Boolean debug) {
109110

110111
@Override
111112
public void apply(ConveyorTile convTile) throws RequestFilterException {
112-
long[] idx = convTile.getTileIndex().clone();
113113
String gridSetId = convTile.getGridSetId();
114114

115115
// Basic bounds test first
116116
try {
117-
convTile.getGridSubset().checkCoverage(idx);
117+
convTile.getGridSubset().checkCoverage(convTile.getIndex());
118118
} catch (OutsideCoverageException oce) {
119119
throw new BlankTileException(this);
120120
}
121121

122+
long x = convTile.getIndex().getX();
123+
long y = convTile.getIndex().getY();
124+
int z = convTile.getIndex().getZ();
122125
int zoomDiff = 0;
123126

124127
// Three scenarios below:
125128
// 1. z is too low , upsample if resampling is enabled
126129
// 2. z is within range, downsample one level and apply
127130
// 3. z is too large , downsample
128-
if (zoomStart != null && idx[2] < zoomStart) {
131+
if (zoomStart != null && z < zoomStart) {
129132
if (resample == null || !resample) {
130133
// Filter does not apply, zoomlevel is too low
131134
return;
132135
} else {
133136
// Upsample
134-
zoomDiff = (int) (idx[2] - zoomStart);
135-
idx[0] = idx[0] << (-1 * zoomDiff);
136-
idx[1] = idx[1] << (-1 * zoomDiff);
137-
idx[2] = zoomStart;
137+
zoomDiff = z - zoomStart;
138+
x = (x << (-1 * zoomDiff));
139+
y = (y << (-1 * zoomDiff));
140+
z = zoomStart;
138141
}
139-
} else if (idx[2] < zoomStop) {
142+
} else if (z < zoomStop) {
140143
// Sample one level higher
141-
idx[0] = idx[0] * 2;
142-
idx[1] = idx[1] * 2;
143-
idx[2] = idx[2] + 1;
144+
x = x * 2;
145+
y = y * 2;
146+
z = z + 1;
144147
} else {
145148
// Reduce to highest supported resolution
146-
zoomDiff = (int) (idx[2] - zoomStop);
147-
idx[0] = idx[0] >> zoomDiff;
148-
idx[1] = idx[1] >> zoomDiff;
149-
idx[2] = zoomStop;
149+
zoomDiff = z - zoomStop;
150+
x = x >> zoomDiff;
151+
y = y >> zoomDiff;
152+
z = zoomStop;
150153
}
151154

155+
TileIndex idx = TileIndex.valueOf(x, y, z);
152156
if (matrices == null
153157
|| matrices.get(gridSetId) == null
154-
|| matrices.get(gridSetId)[(int) idx[2]] == null) {
158+
|| matrices.get(gridSetId)[idx.getZ()] == null) {
155159
try {
156-
setMatrix(convTile.getLayer(), gridSetId, (int) idx[2], false);
160+
setMatrix(convTile.getLayer(), gridSetId, idx.getZ(), false);
157161
} catch (Exception e) {
158162
log.log(
159163
Level.SEVERE,
@@ -162,14 +166,14 @@ public void apply(ConveyorTile convTile) throws RequestFilterException {
162166
+ ", "
163167
+ gridSetId
164168
+ ", "
165-
+ idx[2]
169+
+ idx.getZ()
166170
+ " : "
167171
+ e.getMessage());
168172
throw new RequestFilterException(
169173
this,
170174
500,
171175
"Failed while trying to load filter for "
172-
+ idx[2]
176+
+ idx.getZ()
173177
+ ", please check the logs");
174178
}
175179
}
@@ -229,14 +233,14 @@ public void initialize(TileLayer layer) throws GeoWebCacheException {
229233
}
230234

231235
/** Performs a lookup against an internal raster. */
232-
private boolean lookup(GridSubset grid, long[] idx) {
233-
BufferedImage mat = matrices.get(grid.getName())[(int) idx[2]];
236+
private boolean lookup(GridSubset grid, TileIndex idx) {
237+
BufferedImage mat = matrices.get(grid.getName())[idx.getZ()];
234238

235-
long[] gridCoverage = grid.getCoverage((int) idx[2]);
239+
long[] gridCoverage = grid.getCoverage(idx.getZ());
236240

237241
// Changing index to top left hand origin
238-
long x = idx[0] - gridCoverage[0];
239-
long y = gridCoverage[3] - idx[1];
242+
long x = idx.getX() - gridCoverage[0];
243+
long y = gridCoverage[3] - idx.getY();
240244

241245
return (mat.getRaster().getSample((int) x, (int) y, 0) == 0);
242246
}
@@ -245,14 +249,14 @@ private boolean lookup(GridSubset grid, long[] idx) {
245249
* Performs a lookup against an internal raster. The sampling is actually done against 4 pixels,
246250
* idx should already have been modified to use one level higher than strictly necessary.
247251
*/
248-
private boolean lookupQuad(GridSubset grid, long[] idx) {
249-
BufferedImage mat = matrices.get(grid.getName())[(int) idx[2]];
252+
private boolean lookupQuad(GridSubset grid, TileIndex idx) {
253+
BufferedImage mat = matrices.get(grid.getName())[idx.getZ()];
250254

251-
long[] gridCoverage = grid.getCoverage((int) idx[2]);
255+
long[] gridCoverage = grid.getCoverage(idx.getZ());
252256

253257
// Changing index to top left hand origin
254-
int baseX = (int) (idx[0] - gridCoverage[0]);
255-
int baseY = (int) (gridCoverage[3] - idx[1]);
258+
int baseX = (int) (idx.getX() - gridCoverage[0]);
259+
int baseY = (int) (gridCoverage[3] - idx.getY());
256260

257261
int width = mat.getWidth();
258262
int height = mat.getHeight();
@@ -298,16 +302,16 @@ private boolean lookupQuad(GridSubset grid, long[] idx) {
298302
return hasData;
299303
}
300304

301-
private boolean lookupSubsample(GridSubset grid, long[] idx, int zoomDiff) {
302-
BufferedImage mat = matrices.get(grid.getName())[(int) idx[2]];
305+
private boolean lookupSubsample(GridSubset grid, TileIndex idx, int zoomDiff) {
306+
BufferedImage mat = matrices.get(grid.getName())[idx.getZ()];
303307

304308
int sampleChange = 1 << (-1 * zoomDiff);
305309

306-
long[] gridCoverage = grid.getCoverage((int) idx[2]);
310+
long[] gridCoverage = grid.getCoverage(idx.getZ());
307311

308312
// Changing index to top left hand origin
309-
int baseX = (int) (idx[0] - gridCoverage[0]);
310-
int baseY = (int) (gridCoverage[3] - idx[1]);
313+
int baseX = (int) (idx.getX() - gridCoverage[0]);
314+
int baseY = (int) (gridCoverage[3] - idx.getY());
311315

312316
int width = mat.getWidth();
313317
int height = mat.getHeight();

geowebcache/core/src/main/java/org/geowebcache/filter/security/SecurityDispatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void checkSecurity(final ConveyorTile tile)
5050
final BoundingBox bounds;
5151
final SRS srs;
5252
if (Objects.nonNull(gridSubset)) {
53-
bounds = gridSubset.boundsFromIndex(tile.getTileIndex());
53+
bounds = gridSubset.boundsFromIndex(tile.getIndex());
5454
srs = gridSubset.getSRS();
5555
} else {
5656
bounds = null;

geowebcache/core/src/main/java/org/geowebcache/grid/GridSet.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
2121
import org.apache.commons.lang3.builder.ToStringStyle;
2222
import org.geowebcache.config.Info;
23+
import org.geowebcache.storage.TileIndex;
2324

2425
/** A grid set configuration */
2526
public class GridSet implements Info {
@@ -110,15 +111,19 @@ void setResolutionsPreserved(boolean resolutionsPreserved) {
110111
}
111112

112113
public BoundingBox boundsFromIndex(long[] tileIndex) {
113-
final int tileZ = (int) tileIndex[2];
114+
return boundsFromIndex(TileIndex.valueOf(tileIndex));
115+
}
116+
117+
public BoundingBox boundsFromIndex(TileIndex tileIndex) {
118+
final int tileZ = tileIndex.getZ();
114119
Grid grid = getGrid(tileZ);
115120

116-
final long tileX = tileIndex[0];
121+
final long tileX = tileIndex.getX();
117122
final long tileY;
118123
if (yBaseToggle) {
119-
tileY = tileIndex[1] - grid.getNumTilesHigh();
124+
tileY = tileIndex.getY() - grid.getNumTilesHigh();
120125
} else {
121-
tileY = tileIndex[1];
126+
tileY = tileIndex.getY();
122127
}
123128

124129
double width = grid.getResolution() * getTileWidth();

0 commit comments

Comments
 (0)