From 4a7f0ef9a213e43ab15843cf2473077a69bab37c Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Thu, 30 Jan 2014 10:12:06 +1100 Subject: [PATCH] Resolve memory issue when updating repo. Solves issue # 453. Previously, it was reading one line at a time of the index file. Turns out that the entire index is only on about 5 lines, thus the 5th line is about 2mb. The solution here is to switch to reading a fixed length of 4096 characters at a time rather than entire lines. This ends up a bit more complex (because I wrote a custom tokenizer rather than being able to use Java String methods such as indexOf). There are still other memory issues on low memory devices, to do with trying to parse ~1000 app value objects into memory, each with numerous string objects associated with them. But that particular issue will be solved in the future, with the ContentProvider stuff. --- src/org/fdroid/fdroid/Utils.java | 53 ++++++++++++-------------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/src/org/fdroid/fdroid/Utils.java b/src/org/fdroid/fdroid/Utils.java index 949423b15..767b30048 100644 --- a/src/org/fdroid/fdroid/Utils.java +++ b/src/org/fdroid/fdroid/Utils.java @@ -22,13 +22,7 @@ import android.content.Context; import com.nostra13.universalimageloader.utils.StorageUtils; -import java.io.BufferedReader; -import java.io.Closeable; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.text.SimpleDateFormat; import java.util.Locale; @@ -117,37 +111,30 @@ public final class Utils { public static int countSubstringOccurrence(File file, String substring) throws IOException { int count = 0; - BufferedReader reader = null; + FileReader input = null; try { + int currentSubstringIndex = 0; + char[] buffer = new char[4096]; - reader = new BufferedReader(new FileReader(file)); - while(true) { - String line = reader.readLine(); - if (line == null) { - break; + input = new FileReader(file); + int numRead = input.read(buffer); + while(numRead != -1) { + + for (char c : buffer) { + if (c == substring.charAt(currentSubstringIndex)) { + currentSubstringIndex ++; + if (currentSubstringIndex == substring.length()) { + count ++; + currentSubstringIndex = 0; + } + } else { + currentSubstringIndex = 0; + } } - count += countSubstringOccurrence(line, substring); + numRead = input.read(buffer); } - } finally { - closeQuietly(reader); - } - return count; - } - - /** - * Thanks to http://stackoverflow.com/a/767910 - */ - public static int countSubstringOccurrence(String toSearch, String substring) { - int count = 0; - int index = 0; - while (true) { - index = toSearch.indexOf(substring, index); - if (index == -1){ - break; - } - count ++; - index += substring.length(); + closeQuietly(input); } return count; }