use specialized BinarySort for MapTiles that also repacks the 'sparsed' array
This commit is contained in:
parent
ec647fc4f5
commit
9d2ebab088
@ -17,8 +17,6 @@ package org.oscim.generator;
|
|||||||
import static org.oscim.generator.JobTile.STATE_LOADING;
|
import static org.oscim.generator.JobTile.STATE_LOADING;
|
||||||
import static org.oscim.generator.JobTile.STATE_NONE;
|
import static org.oscim.generator.JobTile.STATE_NONE;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
||||||
*/
|
*/
|
||||||
@ -71,8 +69,12 @@ public class JobQueue {
|
|||||||
if (mJobs == null)
|
if (mJobs == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (mCurrentJob == 0)
|
if (mCurrentJob == 0) {
|
||||||
Arrays.sort(mJobs);
|
//Arrays.sort(mJobs);
|
||||||
|
int len = mJobs.length;
|
||||||
|
if (len > 1)
|
||||||
|
TileDistanceSort.sort(mJobs, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
//return mPriorityQueue.poll();
|
//return mPriorityQueue.poll();
|
||||||
JobTile t = mJobs[mCurrentJob];
|
JobTile t = mJobs[mCurrentJob];
|
||||||
|
@ -21,7 +21,7 @@ import android.util.Log;
|
|||||||
/**
|
/**
|
||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
*/
|
*/
|
||||||
public class JobTile extends Tile implements Comparable<JobTile> {
|
public class JobTile extends Tile {
|
||||||
private final static String TAG = JobTile.class.getName();
|
private final static String TAG = JobTile.class.getName();
|
||||||
|
|
||||||
public final static int STATE_NONE = 0;
|
public final static int STATE_NONE = 0;
|
||||||
@ -59,15 +59,4 @@ public class JobTile extends Tile implements Comparable<JobTile> {
|
|||||||
public JobTile(int tileX, int tileY, byte zoomLevel) {
|
public JobTile(int tileX, int tileY, byte zoomLevel) {
|
||||||
super(tileX, tileY, zoomLevel);
|
super(tileX, tileY, zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(JobTile o) {
|
|
||||||
if (this.distance < o.distance) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (this.distance > o.distance) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2013 OpenScienceMap
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* 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
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@ -14,19 +14,109 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.generator;
|
package org.oscim.generator;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* based on ComparableTimSort:
|
||||||
*
|
* everything below is Copyright OpenJDK, Oracle
|
||||||
*/
|
*/
|
||||||
public class TileDistanceSort implements Comparator<JobTile> {
|
|
||||||
|
|
||||||
@Override
|
public class TileDistanceSort {
|
||||||
public int compare(JobTile tile1, JobTile tile2) {
|
public static void sort(JobTile[] a, int lo, int hi) {
|
||||||
if (tile1.distance == tile2.distance)
|
int nRemaining = hi - lo;
|
||||||
|
if (nRemaining < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int initRunLen = countRunAndMakeAscending(a, lo, hi);
|
||||||
|
binarySort(a, lo, hi, lo + initRunLen);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compareTo(JobTile a, JobTile b) {
|
||||||
|
if (a == null && b == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return tile1.distance > tile2.distance ? 1 : -1;
|
if (a == null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (b == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (a.distance < b.distance) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.distance > b.distance) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void binarySort(JobTile[] a, int lo, int hi, int start)
|
||||||
|
{
|
||||||
|
assert ((lo <= start) && (start <= hi));
|
||||||
|
if (start == lo)
|
||||||
|
++start;
|
||||||
|
for (; start < hi; ++start)
|
||||||
|
{
|
||||||
|
JobTile pivot = a[start];
|
||||||
|
|
||||||
|
int left = lo;
|
||||||
|
int right = start;
|
||||||
|
assert (left <= right);
|
||||||
|
|
||||||
|
while (left < right) {
|
||||||
|
int mid = left + right >>> 1;
|
||||||
|
//if (pivot.compareTo(a[mid]) < 0)
|
||||||
|
if (compareTo(pivot, a[mid]) < 0)
|
||||||
|
right = mid;
|
||||||
|
else
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
assert (left == right);
|
||||||
|
|
||||||
|
int n = start - left;
|
||||||
|
|
||||||
|
switch (n)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
a[(left + 2)] = a[(left + 1)];
|
||||||
|
//$FALL-THROUGH$
|
||||||
|
case 1:
|
||||||
|
a[(left + 1)] = a[left];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.arraycopy(a, left, a, left + 1, n);
|
||||||
|
}
|
||||||
|
a[left] = pivot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int countRunAndMakeAscending(JobTile[] a, int lo, int hi)
|
||||||
|
{
|
||||||
|
assert (lo < hi);
|
||||||
|
int runHi = lo + 1;
|
||||||
|
if (runHi == hi) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compareTo((a[(runHi++)]), a[lo]) < 0) {
|
||||||
|
while ((runHi < hi) && (compareTo((a[runHi]), a[(runHi - 1)]) < 0))
|
||||||
|
++runHi;
|
||||||
|
reverseRange(a, lo, runHi);
|
||||||
|
} else {
|
||||||
|
while ((runHi < hi) && (compareTo((a[runHi]), a[(runHi - 1)]) >= 0)) {
|
||||||
|
++runHi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (runHi - lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void reverseRange(JobTile[] a, int lo, int hi)
|
||||||
|
{
|
||||||
|
--hi;
|
||||||
|
while (lo < hi) {
|
||||||
|
JobTile t = a[lo];
|
||||||
|
a[(lo++)] = a[hi];
|
||||||
|
a[(hi--)] = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import java.util.Arrays;
|
|||||||
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;
|
||||||
|
import org.oscim.generator.TileDistanceSort;
|
||||||
import org.oscim.renderer.layer.TextItem;
|
import org.oscim.renderer.layer.TextItem;
|
||||||
import org.oscim.renderer.layer.VertexPool;
|
import org.oscim.renderer.layer.VertexPool;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
@ -471,10 +472,10 @@ public class TileManager {
|
|||||||
t.vbo = null;
|
t.vbo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTilesCount--;
|
|
||||||
QuadTree.remove(t);
|
QuadTree.remove(t);
|
||||||
|
|
||||||
t.state = STATE_NONE;
|
t.state = STATE_NONE;
|
||||||
|
|
||||||
|
mTilesCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateTileDistances(Object[] tiles, int size, MapPosition mapPosition) {
|
private static void updateTileDistances(Object[] tiles, int size, MapPosition mapPosition) {
|
||||||
@ -536,58 +537,38 @@ public class TileManager {
|
|||||||
|
|
||||||
private static void limitCache(MapPosition mapPosition, int remove) {
|
private static void limitCache(MapPosition mapPosition, int remove) {
|
||||||
MapTile[] tiles = mTiles;
|
MapTile[] tiles = mTiles;
|
||||||
|
int size = mTilesSize;
|
||||||
|
|
||||||
// remove tiles that were never loaded
|
// remove tiles that were never loaded
|
||||||
for (int i = 0, size = mTilesSize; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
if (t == null)
|
if (t == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// make sure tile cannot be used by GL or MapWorker Thread
|
// make sure tile cannot be used by GL or MapWorker Thread
|
||||||
if (t.isLocked() || t.isActive()) {
|
if ((t.state != 0) || t.isLocked()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
clearTile(t);
|
clearTile(t);
|
||||||
tiles[i] = null;
|
tiles[i] = null;
|
||||||
remove--;
|
remove--;
|
||||||
size--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remove > 5) {
|
if (remove > 10) {
|
||||||
int size = mTilesSize;
|
updateTileDistances(tiles, size, mapPosition);
|
||||||
|
|
||||||
if (size > mTilesCount) {
|
// double start, end;
|
||||||
Log.d(TAG, "repack: " + size + " " + mTilesCount);
|
// start = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
int start = 0;
|
TileDistanceSort.sort(tiles, 0, size);
|
||||||
// get first position to shift
|
|
||||||
while (start < size && tiles[start] != null)
|
|
||||||
start++;
|
|
||||||
int space = start + 1;
|
|
||||||
for (int end = 0; end < size;) {
|
|
||||||
// get the number of slots to shift
|
|
||||||
while (space < size && tiles[space] == null)
|
|
||||||
space++;
|
|
||||||
// get the position of next free slots
|
|
||||||
end = space;
|
|
||||||
while (end < size && tiles[end] != null)
|
|
||||||
end++;
|
|
||||||
// number of items to shift
|
|
||||||
int len = end - space;
|
|
||||||
|
|
||||||
if (len > 0) {
|
//end = SystemClock.uptimeMillis();
|
||||||
System.arraycopy(tiles, space, tiles, start, len);
|
//Log.d(TAG, "sort took " + (end - start) +
|
||||||
start = start + len;
|
// "limitCache: repacked: " + mTilesSize + " to: " + mTilesCount);
|
||||||
space = end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(TAG, "repacked tiles to: " + start);
|
|
||||||
Arrays.fill(mTiles, start, mTilesSize, null);
|
|
||||||
mTilesSize = size = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTileDistances(mTiles, size, mapPosition);
|
// sorting also repacks the 'sparse' filled array
|
||||||
Arrays.sort(mTiles, 0, size);
|
// so end of mTiles is at mTilesCount now
|
||||||
|
mTilesSize = size = mTilesCount;
|
||||||
|
|
||||||
for (int i = 1; i < remove; i++) {
|
for (int i = 1; i < remove; i++) {
|
||||||
MapTile t = tiles[size - i];
|
MapTile t = tiles[size - i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user