Some memory optimizations.

- Load all OsuFile String objects into a hash table while parsing, to eliminate duplicate strings.
- Trim all ArrayList objects in OsuFiles.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-01-14 21:48:24 -05:00
parent 62b7ecd648
commit dfeb981361
2 changed files with 39 additions and 11 deletions

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
@ -51,6 +52,11 @@ public class OsuParser {
*/ */
private static int totalDirectories = -1; private static int totalDirectories = -1;
/**
* The string database.
*/
private static HashMap<String, String> stringdb = new HashMap<String, String>();
// This class should not be instantiated. // This class should not be instantiated.
private OsuParser() {} private OsuParser() {}
@ -92,11 +98,15 @@ public class OsuParser {
parseFile(file, osuFiles, false); parseFile(file, osuFiles, false);
} }
if (!osuFiles.isEmpty()) { // add entry if non-empty if (!osuFiles.isEmpty()) { // add entry if non-empty
osuFiles.trimToSize();
Collections.sort(osuFiles); Collections.sort(osuFiles);
OsuGroupList.get().addSongGroup(osuFiles); OsuGroupList.get().addSongGroup(osuFiles);
} }
} }
// clear string DB
stringdb = new HashMap<String, String>();
currentFile = null; currentFile = null;
currentDirectoryIndex = -1; currentDirectoryIndex = -1;
totalDirectories = -1; totalDirectories = -1;
@ -153,7 +163,7 @@ public class OsuParser {
osu.countdown = Byte.parseByte(tokens[1]); osu.countdown = Byte.parseByte(tokens[1]);
break; break;
case "SampleSet": case "SampleSet":
osu.sampleSet = tokens[1]; osu.sampleSet = getDBString(tokens[1]);
break; break;
case "StackLeniency": case "StackLeniency":
osu.stackLeniency = Float.parseFloat(tokens[1]); osu.stackLeniency = Float.parseFloat(tokens[1]);
@ -234,28 +244,28 @@ public class OsuParser {
try { try {
switch (tokens[0]) { switch (tokens[0]) {
case "Title": case "Title":
osu.title = tokens[1]; osu.title = getDBString(tokens[1]);
break; break;
case "TitleUnicode": case "TitleUnicode":
osu.titleUnicode = tokens[1]; osu.titleUnicode = getDBString(tokens[1]);
break; break;
case "Artist": case "Artist":
osu.artist = tokens[1]; osu.artist = getDBString(tokens[1]);
break; break;
case "ArtistUnicode": case "ArtistUnicode":
osu.artistUnicode = tokens[1]; osu.artistUnicode = getDBString(tokens[1]);
break; break;
case "Creator": case "Creator":
osu.creator = tokens[1]; osu.creator = getDBString(tokens[1]);
break; break;
case "Version": case "Version":
osu.version = tokens[1]; osu.version = getDBString(tokens[1]);
break; break;
case "Source": case "Source":
osu.source = tokens[1]; osu.source = getDBString(tokens[1]);
break; break;
case "Tags": case "Tags":
osu.tags = tokens[1].toLowerCase(); osu.tags = getDBString(tokens[1].toLowerCase());
break; break;
case "BeatmapID": case "BeatmapID":
osu.beatmapID = Integer.parseInt(tokens[1]); osu.beatmapID = Integer.parseInt(tokens[1]);
@ -321,7 +331,7 @@ public class OsuParser {
tokens[2] = tokens[2].replaceAll("^\"|\"$", ""); tokens[2] = tokens[2].replaceAll("^\"|\"$", "");
String ext = OsuParser.getExtension(tokens[2]); String ext = OsuParser.getExtension(tokens[2]);
if (ext.equals("jpg") || ext.equals("png")) if (ext.equals("jpg") || ext.equals("png"))
osu.bg = file.getParent() + File.separator + tokens[2]; osu.bg = getDBString(file.getParent() + File.separator + tokens[2]);
break; break;
case "2": // break periods case "2": // break periods
try { try {
@ -339,6 +349,8 @@ public class OsuParser {
break; break;
} }
} }
if (osu.breaks != null)
osu.breaks.trimToSize();
break; break;
case "[TimingPoints]": case "[TimingPoints]":
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
@ -369,6 +381,7 @@ public class OsuParser {
line, file.getAbsolutePath()), e); line, file.getAbsolutePath()), e);
} }
} }
osu.timingPoints.trimToSize();
break; break;
case "[Colours]": case "[Colours]":
LinkedList<Color> colors = new LinkedList<Color>(); LinkedList<Color> colors = new LinkedList<Color>();
@ -586,4 +599,19 @@ public class OsuParser {
return currentDirectoryIndex * 100 / totalDirectories; return currentDirectoryIndex * 100 / totalDirectories;
} }
/**
* Returns the String object in the database for the given String.
* If none, insert the String into the database and return the original String.
* @param s the string to retrieve
* @return the string object
*/
private static String getDBString(String s) {
String DBString = stringdb.get(s);
if (DBString == null) {
stringdb.put(s, s);
return s;
} else
return DBString;
}
} }

View File

@ -698,7 +698,7 @@ public class Options extends BasicGameState {
int subtextWidth = Utils.FONT_DEFAULT.getWidth("Click or drag an option to change it."); int subtextWidth = Utils.FONT_DEFAULT.getWidth("Click or drag an option to change it.");
float tabX = (width / 50) + (tab.getWidth() / 2f); float tabX = (width / 50) + (tab.getWidth() / 2f);
float tabY = 15 + Utils.FONT_XLARGE.getLineHeight() + (tab.getHeight() / 2f); float tabY = 15 + Utils.FONT_XLARGE.getLineHeight() + (tab.getHeight() / 2f);
float tabOffset = (float) Math.min(tab.getWidth(), int tabOffset = Math.min(tab.getWidth(),
((width - subtextWidth - tab.getWidth()) / 2) / TAB_MAX); ((width - subtextWidth - tab.getWidth()) / 2) / TAB_MAX);
for (int i = 0; i < optionTabs.length; i++) for (int i = 0; i < optionTabs.length; i++)
optionTabs[i] = new MenuButton(tab, tabX + (i * tabOffset), tabY); optionTabs[i] = new MenuButton(tab, tabX + (i * tabOffset), tabY);