Merge "UsageStatsService: Update file index to prevent double checkin" into lmp-mr1-dev

This commit is contained in:
Adam Lesinski
2014-11-08 02:07:44 +00:00
committed by Android (Google) Code Review
2 changed files with 31 additions and 14 deletions

View File

@@ -40,6 +40,7 @@ class UsageStatsDatabase {
private static final String TAG = "UsageStatsDatabase"; private static final String TAG = "UsageStatsDatabase";
private static final boolean DEBUG = UsageStatsService.DEBUG; private static final boolean DEBUG = UsageStatsService.DEBUG;
private static final String BAK_SUFFIX = ".bak"; private static final String BAK_SUFFIX = ".bak";
private static final String CHECKED_IN_SUFFIX = UsageStatsXml.CHECKED_IN_SUFFIX;
private final Object mLock = new Object(); private final Object mLock = new Object();
private final File[] mIntervalDirs; private final File[] mIntervalDirs;
@@ -114,14 +115,17 @@ class UsageStatsDatabase {
final TimeSparseArray<AtomicFile> files = final TimeSparseArray<AtomicFile> files =
mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY]; mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY];
final int fileCount = files.size(); final int fileCount = files.size();
int start = 0;
while (start < fileCount - 1) { // We may have holes in the checkin (if there was an error)
if (!files.valueAt(start).getBaseFile().getName().endsWith("-c")) { // so find the last checked-in file and go from there.
break; int lastCheckin = -1;
for (int i = 0; i < fileCount - 1; i++) {
if (files.valueAt(i).getBaseFile().getPath().endsWith(CHECKED_IN_SUFFIX)) {
lastCheckin = i;
} }
start++;
} }
final int start = lastCheckin + 1;
if (start == fileCount - 1) { if (start == fileCount - 1) {
return true; return true;
} }
@@ -143,8 +147,8 @@ class UsageStatsDatabase {
// are marked as checked-in. // are marked as checked-in.
for (int i = start; i < fileCount - 1; i++) { for (int i = start; i < fileCount - 1; i++) {
final AtomicFile file = files.valueAt(i); final AtomicFile file = files.valueAt(i);
final File checkedInFile = new File(file.getBaseFile().getParent(), final File checkedInFile = new File(
file.getBaseFile().getName() + "-c"); file.getBaseFile().getPath() + CHECKED_IN_SUFFIX);
if (!file.getBaseFile().renameTo(checkedInFile)) { if (!file.getBaseFile().renameTo(checkedInFile)) {
// We must return success, as we've already marked some files as checked-in. // We must return success, as we've already marked some files as checked-in.
// It's better to repeat ourselves than to lose data. // It's better to repeat ourselves than to lose data.
@@ -152,6 +156,10 @@ class UsageStatsDatabase {
+ " as checked-in"); + " as checked-in");
return true; return true;
} }
// AtomicFile needs to set a new backup path with the same -c extension, so
// we replace the old AtomicFile with the updated one.
files.setValueAt(i, new AtomicFile(checkedInFile));
} }
} }
return true; return true;
@@ -240,8 +248,13 @@ class UsageStatsDatabase {
} catch (IOException e) { } catch (IOException e) {
// Ignore, this is just to make sure there are no backups. // Ignore, this is just to make sure there are no backups.
} }
final File newFile = new File(file.getBaseFile().getParentFile(),
Long.toString(newTime)); String newName = Long.toString(newTime);
if (file.getBaseFile().getName().endsWith(CHECKED_IN_SUFFIX)) {
newName = newName + CHECKED_IN_SUFFIX;
}
final File newFile = new File(file.getBaseFile().getParentFile(), newName);
Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to " Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to "
+ newFile.getAbsolutePath()); + newFile.getAbsolutePath());
file.getBaseFile().renameTo(newFile); file.getBaseFile().renameTo(newFile);

View File

@@ -31,17 +31,21 @@ public class UsageStatsXml {
private static final int CURRENT_VERSION = 1; private static final int CURRENT_VERSION = 1;
private static final String USAGESTATS_TAG = "usagestats"; private static final String USAGESTATS_TAG = "usagestats";
private static final String VERSION_ATTR = "version"; private static final String VERSION_ATTR = "version";
private static final String CHECKED_IN_SUFFIX = "-c"; static final String CHECKED_IN_SUFFIX = "-c";
public static long parseBeginTime(AtomicFile file) { public static long parseBeginTime(AtomicFile file) {
return parseBeginTime(file.getBaseFile()); return parseBeginTime(file.getBaseFile());
} }
public static long parseBeginTime(File file) { public static long parseBeginTime(File file) {
final String name = file.getName(); String name = file.getName();
if (name.endsWith(CHECKED_IN_SUFFIX)) {
return Long.parseLong( // Eat as many occurrences of -c as possible. This is due to a bug where -c
name.substring(0, name.length() - CHECKED_IN_SUFFIX.length())); // would be appended more than once to a checked-in file, causing a crash
// on boot when indexing files since Long.parseLong() will puke on anything but
// a number.
while (name.endsWith(CHECKED_IN_SUFFIX)) {
name = name.substring(0, name.length() - CHECKED_IN_SUFFIX.length());
} }
return Long.parseLong(name); return Long.parseLong(name);
} }