Cleanup: removed descending iterator for TrackPoints.

This commit is contained in:
Dennis Guse
2020-12-25 16:55:12 +01:00
parent ccd93dd17d
commit a689b6eb2c
8 changed files with 37 additions and 119 deletions
@@ -87,50 +87,37 @@ public class CustomContentProviderUtilsTest {
@Test @Test
public void testLocationIterator_noPoints() { public void testLocationIterator_noPoints() {
testIterator(new Track.Id(1), 0, 1, false); testIterator(new Track.Id(1), 0, 1);
} }
@Test @Test
public void testLocationIterator_noBatchAscending() { public void testLocationIterator_noBatchAscending() {
testIterator(new Track.Id(1), 50, 100, false); testIterator(new Track.Id(1), 50, 100);
testIterator(new Track.Id(2), 50, 50, false); testIterator(new Track.Id(2), 50, 50);
}
@Test
public void testLocationIterator_noBatchDescending() {
testIterator(new Track.Id(1), 50, 100, true);
testIterator(new Track.Id(2), 50, 50, true);
} }
@Test @Test
public void testLocationIterator_batchAscending() { public void testLocationIterator_batchAscending() {
testIterator(new Track.Id(1), 50, 11, false); testIterator(new Track.Id(1), 50, 11);
testIterator(new Track.Id(2), 50, 25, false); testIterator(new Track.Id(2), 50, 25);
}
@Test
public void testLocationIterator_batchDescending() {
testIterator(new Track.Id(1), 50, 11, true);
testIterator(new Track.Id(2), 50, 25, true);
} }
@Test @Test
public void testLocationIterator_largeTrack() { public void testLocationIterator_largeTrack() {
testIterator(new Track.Id(1), 20000, 2000, false); testIterator(new Track.Id(1), 20000, 2000);
} }
private void testIterator(Track.Id trackId, int numPoints, int batchSize, boolean descending) { private void testIterator(Track.Id trackId, int numPoints, int batchSize) {
long lastPointId = initializeTrack(trackId, numPoints); long lastPointId = initializeTrack(trackId, numPoints);
contentProviderUtils.setDefaultCursorBatchSize(batchSize); contentProviderUtils.setDefaultCursorBatchSize(batchSize);
List<TrackPoint> locations = new ArrayList<>(numPoints); List<TrackPoint> locations = new ArrayList<>(numPoints);
try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L, descending)) { try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L)) {
while (it.hasNext()) { while (it.hasNext()) {
TrackPoint loc = it.next(); TrackPoint loc = it.next();
assertNotNull(loc); assertNotNull(loc);
locations.add(loc); locations.add(loc);
// Make sure the IDs are returned in the right order. // Make sure the IDs are returned in the right order.
assertEquals(descending ? lastPointId - locations.size() + 1 assertEquals(lastPointId - numPoints + locations.size(), it.getTrackPointId());
: lastPointId - numPoints + locations.size(), it.getTrackPointId());
} }
assertEquals(numPoints, locations.size()); assertEquals(numPoints, locations.size());
} }
@@ -158,7 +145,7 @@ public class CustomContentProviderUtilsTest {
// Load all inserted trackPoints. // Load all inserted trackPoints.
long lastPointId = -1; long lastPointId = -1;
int counter = 0; int counter = 0;
try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, -1L, false)) { try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, -1L)) {
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
lastPointId = it.getTrackPointId(); lastPointId = it.getTrackPointId();
@@ -778,9 +765,9 @@ public class CustomContentProviderUtilsTest {
// when / then // when / then
contentProviderUtils.bulkInsertTrackPoint(track.second, trackId); contentProviderUtils.bulkInsertTrackPoint(track.second, trackId);
assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000).getCount());
contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(track.second, 0, 8), trackId); contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(track.second, 0, 8), trackId);
assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000).getCount());
} }
/** /**
@@ -875,31 +862,6 @@ public class CustomContentProviderUtilsTest {
checkLocation(9, lastTrackPoint.getLocation()); checkLocation(9, lastTrackPoint.getLocation());
} }
/**
* Tests the method {@link ContentProviderUtils#getTrackPointCursor(Track.Id, long, int, boolean)} in descending.
*/
@Test
public void testGetTrackPointCursor_desc() {
// given
Track.Id trackId = new Track.Id(System.currentTimeMillis());
Pair<Track, TrackPoint[]> track = TestDataUtil.createTrack(trackId, 10);
contentProviderUtils.insertTrack(track.first);
long[] trackpointIds = new long[track.second.length];
for (int i = 0; i < trackpointIds.length; i++) {
trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.second[i], track.first.getId()));
}
// when
Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[1], 5, true);
// then
assertEquals(2, cursor.getCount());
}
/**
* Tests the method {@link ContentProviderUtils#getTrackPointCursor(Track.Id, long, int, boolean)} in ascending.
*/
@Test @Test
public void testGetTrackPointCursor_asc() { public void testGetTrackPointCursor_asc() {
// given // given
@@ -913,44 +875,12 @@ public class CustomContentProviderUtilsTest {
} }
// when // when
Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5, false); Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5);
// then // then
assertEquals(2, cursor.getCount()); assertEquals(2, cursor.getCount());
} }
/**
* Tests the method {@link ContentProviderUtils#getTrackPointLocationIterator(Track.Id, long, boolean)} in descending.
*/
@Test
public void testGetTrackPointLocationIterator_desc() {
// given
Track.Id trackId = new Track.Id(System.currentTimeMillis());
Pair<Track, TrackPoint[]> track = TestDataUtil.createTrack(trackId, 10);
contentProviderUtils.insertTrack(track.first);
long[] trackpointIds = new long[track.second.length];
for (int i = 0; i < trackpointIds.length; i++) {
trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.second[i], track.first.getId()));
}
long startTrackPointId = trackpointIds[9];
// when
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId, true);
// then
for (int i = 0; i < trackpointIds.length; i++) {
assertTrue(trackPointIterator.hasNext());
TrackPoint trackPoint = trackPointIterator.next();
assertEquals(startTrackPointId - i, trackPointIterator.getTrackPointId());
checkLocation((trackpointIds.length - 1) - i, trackPoint.getLocation());
}
assertFalse(trackPointIterator.hasNext());
}
/**
* Tests the method {@link ContentProviderUtils#getTrackPointLocationIterator(Track.Id, long, boolean)} in ascending.
*/
@Test @Test
public void testGetTrackPointLocationIterator_asc() { public void testGetTrackPointLocationIterator_asc() {
// given // given
@@ -966,7 +896,7 @@ public class CustomContentProviderUtilsTest {
long startTrackPointId = trackpointIds[0]; long startTrackPointId = trackpointIds[0];
// when // when
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId, false); TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId);
// then // then
for (int i = 0; i < trackpointIds.length; i++) { for (int i = 0; i < trackpointIds.length; i++) {
@@ -364,7 +364,7 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL
int samplingFrequency = -1; int samplingFrequency = -1;
boolean includeNextPoint = false; boolean includeNextPoint = false;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, localLastSeenTrackPointIdId + 1, false)) { try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, localLastSeenTrackPointIdId + 1)) {
while (trackPointIterator.hasNext()) { while (trackPointIterator.hasNext()) {
TrackPoint trackPoint = trackPointIterator.next(); TrackPoint trackPoint = trackPointIterator.next();
@@ -680,27 +680,22 @@ public class ContentProviderUtils {
* Creates a location cursor. The caller owns the returned cursor and is responsible for closing it. * Creates a location cursor. The caller owns the returned cursor and is responsible for closing it.
* *
* @param trackId the track id * @param trackId the track id
* @param startTrackPointId the starting trackPoint id. -1L to ignore * @param startTrackPointId the starting trackPoint id. `null` to ignore
* @param maxLocations maximum number of locations to return. -1 for no limit * @param maxLocations maximum number of locations to return. `null` for no limit
* @param descending true to sort the result in descending order (latest location first)
*/ */
public Cursor getTrackPointCursor(Track.Id trackId, long startTrackPointId, int maxLocations, boolean descending) { public Cursor getTrackPointCursor(Track.Id trackId, Long startTrackPointId, Integer maxLocations) {
String selection; String selection;
String[] selectionArgs; String[] selectionArgs;
if (startTrackPointId >= 0) { if (startTrackPointId != null) {
String comparison = descending ? "<=" : ">="; selection = TrackPointsColumns.TRACKID + "=? AND " + TrackPointsColumns._ID + ">=?";
selection = TrackPointsColumns.TRACKID + "=? AND " + TrackPointsColumns._ID + comparison + "?";
selectionArgs = new String[]{Long.toString(trackId.getId()), Long.toString(startTrackPointId)}; selectionArgs = new String[]{Long.toString(trackId.getId()), Long.toString(startTrackPointId)};
} else { } else {
selection = TrackPointsColumns.TRACKID + "=?"; selection = TrackPointsColumns.TRACKID + "=?";
selectionArgs = new String[]{Long.toString(trackId.getId())}; selectionArgs = new String[]{Long.toString(trackId.getId())};
} }
String sortOrder = TrackPointsColumns._ID; String sortOrder = TrackPointsColumns.DEFAULT_SORT_ORDER;
if (descending) { if (maxLocations != null) {
sortOrder += " DESC";
}
if (maxLocations >= 0) {
sortOrder += " LIMIT " + maxLocations; sortOrder += " LIMIT " + maxLocations;
} }
return getTrackPointCursor(null, selection, selectionArgs, sortOrder); return getTrackPointCursor(null, selection, selectionArgs, sortOrder);
@@ -784,11 +779,10 @@ public class ContentProviderUtils {
* When done with iteration, {@link TrackPointIterator#close()} must be called. * When done with iteration, {@link TrackPointIterator#close()} must be called.
* *
* @param trackId the track id * @param trackId the track id
* @param startTrackPointId the starting trackPoint id. -1L to ignore * @param startTrackPointId the starting trackPoint id. `null` to ignore
* @param descending true to sort the result in descending order (latest location first)
*/ */
public TrackPointIterator getTrackPointLocationIterator(final Track.Id trackId, final long startTrackPointId, final boolean descending) { public TrackPointIterator getTrackPointLocationIterator(final Track.Id trackId, final Long startTrackPointId) {
return new TrackPointIterator(this, trackId, startTrackPointId, descending); return new TrackPointIterator(this, trackId, startTrackPointId);
} }
private TrackPoint findTrackPointBy(String selection, String[] selectionArgs) { private TrackPoint findTrackPointBy(String selection, String[] selectionArgs) {
@@ -816,7 +810,7 @@ public class ContentProviderUtils {
public List<TrackPoint> getTrackPoints(Track.Id trackId) { public List<TrackPoint> getTrackPoints(Track.Id trackId) {
List<TrackPoint> trackPoints = null; List<TrackPoint> trackPoints = null;
try (Cursor trackPointCursor = getTrackPointCursor(trackId, -1L, -1, false)) { try (Cursor trackPointCursor = getTrackPointCursor(trackId, -1L, -1)) {
if (trackPointCursor != null) { if (trackPointCursor != null) {
trackPointCursor.moveToFirst(); trackPointCursor.moveToFirst();
trackPoints = new ArrayList<>(trackPointCursor.getCount()); trackPoints = new ArrayList<>(trackPointCursor.getCount());
@@ -18,16 +18,14 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
private final ContentProviderUtils contentProviderUtils; private final ContentProviderUtils contentProviderUtils;
private final Track.Id trackId; private final Track.Id trackId;
private final boolean descending;
private final CachedTrackPointsIndexes indexes; private final CachedTrackPointsIndexes indexes;
private long lastTrackPointId = -1L; private long lastTrackPointId = -1L;
private Cursor cursor; private Cursor cursor;
public TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, long startTrackPointId, boolean descending) { public TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, Long startTrackPointId) {
this.contentProviderUtils = contentProviderUtils; this.contentProviderUtils = contentProviderUtils;
this.trackId = trackId; this.trackId = trackId;
this.descending = descending;
cursor = getCursor(startTrackPointId); cursor = getCursor(startTrackPointId);
indexes = cursor != null ? new CachedTrackPointsIndexes(cursor) indexes = cursor != null ? new CachedTrackPointsIndexes(cursor)
@@ -40,14 +38,14 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
* @param trackPointId the starting track point id * @param trackPointId the starting track point id
*/ */
private Cursor getCursor(long trackPointId) { private Cursor getCursor(long trackPointId) {
return contentProviderUtils.getTrackPointCursor(trackId, trackPointId, contentProviderUtils.getDefaultCursorBatchSize(), descending); return contentProviderUtils.getTrackPointCursor(trackId, trackPointId, contentProviderUtils.getDefaultCursorBatchSize());
} }
/** /**
* Advances the cursor to the next batch. Returns true if successful. * Advances the cursor to the next batch. Returns true if successful.
*/ */
private boolean advanceCursorToNextBatch() { private boolean advanceCursorToNextBatch() {
long trackPointId = lastTrackPointId == -1L ? -1L : lastTrackPointId + (descending ? -1 : 1); long trackPointId = lastTrackPointId == -1L ? -1L : lastTrackPointId + 1;
Log.d(TAG, "Advancing track point id: " + trackPointId); Log.d(TAG, "Advancing track point id: " + trackPointId);
cursor.close(); cursor.close();
cursor = getCursor(trackPointId); cursor = getCursor(trackPointId);
@@ -126,7 +126,7 @@ public class FileTrackExporter implements TrackExporter {
boolean isLastLocationValid = false; boolean isLastLocationValid = false;
TrackPoint lastTrackPoint = null; TrackPoint lastTrackPoint = null;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false)) { try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L)) {
while (trackPointIterator.hasNext()) { while (trackPointIterator.hasNext()) {
if (Thread.interrupted()) { if (Thread.interrupted()) {
@@ -16,7 +16,6 @@
package de.dennisguse.opentracks.io.file.exporter; package de.dennisguse.opentracks.io.file.exporter;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import android.location.Location; import android.location.Location;
import java.io.OutputStream; import java.io.OutputStream;
@@ -403,15 +402,12 @@ public class KmlTrackWriter implements TrackWriter {
if (trackPointId == -1L) { if (trackPointId == -1L) {
return location.getBearing(); return location.getBearing();
} }
TrackPoint viewLocation; TrackPoint viewLocation = contentProviderUtils.getLastValidTrackPoint(trackId);
try (Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackPointId, 10, true)) { if (viewLocation != null) {
if (cursor == null || cursor.getCount() == 0) { return viewLocation.bearingTo(location);
return location.getBearing();
}
cursor.moveToPosition(cursor.getCount() - 1);
viewLocation = contentProviderUtils.createTrackPoint(cursor);
} }
return viewLocation.bearingTo(location);
return location.getBearing();
} }
private String getCoordinates(Location location, String separator) { private String getCoordinates(Location location, String separator) {
@@ -160,7 +160,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
// TODO Should not be necessary anymore? // TODO Should not be necessary anymore?
TrackStatisticsUpdater markerTrackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics().getStartTime_ms()); TrackStatisticsUpdater markerTrackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics().getStartTime_ms());
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false)) { try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L)) {
while (true) { while (true) {
if (marker == null) { if (marker == null) {
@@ -352,7 +352,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics().getStartTime_ms()); trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics().getStartTime_ms());
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false)) { try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L)) {
trackStatisticsUpdater.addTrackPoint(trackPointIterator, recordingDistanceInterval); trackStatisticsUpdater.addTrackPoint(trackPointIterator, recordingDistanceInterval);
} catch (RuntimeException e) { } catch (RuntimeException e) {
Log.e(TAG, "RuntimeException", e); Log.e(TAG, "RuntimeException", e);