TrackPointIterator: removed manual batching as it should not be necessary.

This commit is contained in:
Dennis Guse
2021-03-06 17:12:44 +01:00
parent a5158a55d9
commit 7d2a6fff59
4 changed files with 36 additions and 95 deletions
@@ -70,7 +70,6 @@ public class ContentProviderUtils {
private static final String ID_SEPARATOR = ",";
private final ContentResolver contentResolver;
private int defaultCursorBatchSize = 2000;
public ContentProviderUtils(Context context) {
contentResolver = context.getContentResolver();
@@ -176,7 +175,7 @@ public class ContentProviderUtils {
// Delete track last since it triggers a database vacuum call
String whereClause = String.format(TracksColumns._ID + " IN (%s)", TextUtils.join(",", Collections.nCopies(trackIds.size(), "?")));
contentResolver.delete(TracksColumns.CONTENT_URI, whereClause, trackIds.stream().map(id->Long.toString(id.getId())).toArray(String[]::new));
contentResolver.delete(TracksColumns.CONTENT_URI, whereClause, trackIds.stream().map(id -> Long.toString(id.getId())).toArray(String[]::new));
}
public void deleteTrack(Context context, @NonNull Track.Id trackId) {
@@ -632,9 +631,9 @@ public class ContentProviderUtils {
*
* @param trackId the track id
* @param startTrackPointId the starting trackPoint id. `null` to ignore
* @param maxLocations maximum number of locations to return. `null` for no limit
*/
public Cursor getTrackPointCursor(Track.Id trackId, TrackPoint.Id startTrackPointId, Integer maxLocations) {
@NonNull
public Cursor getTrackPointCursor(@NonNull Track.Id trackId, TrackPoint.Id startTrackPointId) {
String selection;
String[] selectionArgs;
if (startTrackPointId != null) {
@@ -645,11 +644,7 @@ public class ContentProviderUtils {
selectionArgs = new String[]{Long.toString(trackId.getId())};
}
String sortOrder = TrackPointsColumns.DEFAULT_SORT_ORDER;
if (maxLocations != null) {
sortOrder += " LIMIT " + maxLocations;
}
return getTrackPointCursor(null, selection, selectionArgs, sortOrder);
return getTrackPointCursor(null, selection, selectionArgs, TrackPointsColumns.DEFAULT_SORT_ORDER);
}
/**
@@ -763,39 +758,23 @@ public class ContentProviderUtils {
return contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, projection, selection, selectionArgs, sortOrder);
}
@Deprecated //Use TrackPointIterator instead
@VisibleForTesting
public List<TrackPoint> getTrackPoints(Track.Id trackId) {
List<TrackPoint> trackPoints = null;
List<TrackPoint> trackPoints;
try (Cursor trackPointCursor = getTrackPointCursor(trackId, null, null)) {
if (trackPointCursor != null) {
trackPointCursor.moveToFirst();
trackPoints = new ArrayList<>(trackPointCursor.getCount());
for (int i = 0; i < trackPointCursor.getCount(); i++) {
trackPoints.add(createTrackPoint(trackPointCursor));
trackPointCursor.moveToNext();
}
try (Cursor trackPointCursor = getTrackPointCursor(trackId, null)) {
trackPointCursor.moveToFirst();
trackPoints = new ArrayList<>(trackPointCursor.getCount());
for (int i = 0; i < trackPointCursor.getCount(); i++) {
trackPoints.add(createTrackPoint(trackPointCursor));
trackPointCursor.moveToNext();
}
}
return trackPoints;
}
int getDefaultCursorBatchSize() {
return defaultCursorBatchSize;
}
/**
* Sets the default cursor batch size. For testing purpose.
*
* @param defaultCursorBatchSize the default cursor batch size
*/
@VisibleForTesting
void setDefaultCursorBatchSize(int defaultCursorBatchSize) {
this.defaultCursorBatchSize = defaultCursorBatchSize;
}
public static String formatIdListForUri(Track.Id... trackIds) {
long[] ids = new long[trackIds.length];
for (int i = 0; i < trackIds.length; i++) {
@@ -1,7 +1,8 @@
package de.dennisguse.opentracks.content.provider;
import android.database.Cursor;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -10,9 +11,8 @@ import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
/**
* A lightweight wrapper around the original {@link Cursor} with a method to clean up.
* A lightweight wrapper around the original {@link Cursor}.
*/
//TODO Remove batching; that should be handled by the database/contentprovider (i.e., already in place as we use a cursor)!
public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
private static final String TAG = TrackPointIterator.class.getSimpleName();
@@ -20,7 +20,6 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
private final ContentProviderUtils contentProviderUtils;
private final Track.Id trackId;
private final CachedTrackPointsIndexes indexes;
private TrackPoint.Id lastTrackPointId = null;
private Cursor cursor;
public TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, TrackPoint.Id startTrackPointId) {
@@ -28,28 +27,11 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
this.trackId = trackId;
cursor = getCursor(startTrackPointId);
indexes = cursor != null ? new CachedTrackPointsIndexes(cursor)
: null;
indexes = new CachedTrackPointsIndexes(cursor);
}
/**
* Gets the track point cursor.
*
* @param trackPointId the starting track point id
*/
private Cursor getCursor(TrackPoint.Id trackPointId) {
return contentProviderUtils.getTrackPointCursor(trackId, trackPointId, contentProviderUtils.getDefaultCursorBatchSize());
}
/**
* Advances the cursor to the next batch. Returns true if successful.
*/
private boolean advanceCursorToNextBatch() {
TrackPoint.Id trackPointId = lastTrackPointId == null ? null : new TrackPoint.Id(lastTrackPointId.getId() + 1);
Log.d(TAG, "Advancing track point id: " + trackPointId);
cursor.close();
cursor = getCursor(trackPointId);
return cursor != null;
return contentProviderUtils.getTrackPointCursor(trackId, trackPointId);
}
@Override
@@ -57,29 +39,15 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
if (cursor == null) {
return false;
}
if (cursor.isAfterLast()) {
return false;
}
if (cursor.isLast()) {
if (cursor.getCount() != contentProviderUtils.getDefaultCursorBatchSize()) {
return false;
}
return advanceCursorToNextBatch() && !cursor.isAfterLast();
}
return true;
return !cursor.isLast() && !cursor.isAfterLast();
}
@Override
@NonNull
public TrackPoint next() {
if (cursor == null) {
if (cursor == null || !cursor.moveToNext()) {
throw new NoSuchElementException();
}
if (!cursor.moveToNext()) {
if (!advanceCursorToNextBatch() || !cursor.moveToNext()) {
throw new NoSuchElementException();
}
}
lastTrackPointId = new TrackPoint.Id(cursor.getLong(indexes.idIndex));
return ContentProviderUtils.fillTrackPoint(cursor, indexes);
}
@@ -172,6 +172,7 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
Track track = contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(sharedPreferences, context));
String category = track != null ? track.getCategory() : "";
//TODO Querying all TrackPoints all the time is inefficient; use TrackDataHub
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(track.getId());
boolean isMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
boolean isReportSpeed = PreferencesUtils.isReportSpeed(sharedPreferences, context, category);