Skip to content

Commit 7ead28e

Browse files
authored
Merge pull request #2524 from capdevon/capdevon-BinaryExporter
Refactor: BinaryExporter optimization + javadoc
2 parents 112ff1f + e1d4675 commit 7ead28e

File tree

1 file changed

+46
-45
lines changed

1 file changed

+46
-45
lines changed

jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2021 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,13 @@
3838
import com.jme3.export.Savable;
3939
import com.jme3.export.SavableClassUtil;
4040
import com.jme3.math.FastMath;
41-
import java.io.*;
41+
42+
import java.io.BufferedOutputStream;
43+
import java.io.ByteArrayOutputStream;
44+
import java.io.File;
45+
import java.io.FileOutputStream;
46+
import java.io.IOException;
47+
import java.io.OutputStream;
4248
import java.util.ArrayList;
4349
import java.util.HashMap;
4450
import java.util.IdentityHashMap;
@@ -116,39 +122,40 @@
116122
*
117123
* @author Joshua Slack
118124
*/
119-
120125
public class BinaryExporter implements JmeExporter {
121-
private static final Logger logger = Logger.getLogger(BinaryExporter.class
122-
.getName());
126+
127+
private static final Logger logger = Logger.getLogger(BinaryExporter.class.getName());
123128

124129
protected int aliasCount = 1;
125130
protected int idCount = 1;
126131

127-
private final IdentityHashMap<Savable, BinaryIdContentPair> contentTable
128-
= new IdentityHashMap<>();
129-
130-
protected HashMap<Integer, Integer> locationTable
131-
= new HashMap<>();
132+
private final IdentityHashMap<Savable, BinaryIdContentPair> contentTable = new IdentityHashMap<>();
133+
protected HashMap<Integer, Integer> locationTable = new HashMap<>();
132134

133135
// key - class name, value = bco
134-
private final HashMap<String, BinaryClassObject> classes
135-
= new HashMap<>();
136-
136+
private final HashMap<String, BinaryClassObject> classes = new HashMap<>();
137137
private final ArrayList<Savable> contentKeys = new ArrayList<>();
138138

139139
public static boolean debug = false;
140140
public static boolean useFastBufs = true;
141141

142+
/**
143+
* Constructs a new {@code BinaryExporter}.
144+
*/
142145
public BinaryExporter() {
143146
}
144147

148+
/**
149+
* Returns a new instance of {@code BinaryExporter}.
150+
*
151+
* @return A new {@code BinaryExporter} instance.
152+
*/
145153
public static BinaryExporter getInstance() {
146154
return new BinaryExporter();
147155
}
148156

149157
/**
150158
* Saves the object into memory then loads it from memory.
151-
*
152159
* Used by tests to check if the persistence system is working.
153160
*
154161
* @param <T> The type of savable.
@@ -163,9 +170,11 @@ public static <T extends Savable> T saveAndLoad(AssetManager assetManager, T obj
163170
try {
164171
BinaryExporter exporter = new BinaryExporter();
165172
exporter.save(object, baos);
173+
166174
BinaryImporter importer = new BinaryImporter();
167175
importer.setAssetManager(assetManager);
168176
return (T) importer.load(baos.toByteArray());
177+
169178
} catch (IOException ex) {
170179
// Should never happen.
171180
throw new AssertionError(ex);
@@ -191,28 +200,25 @@ public void save(Savable object, OutputStream os) throws IOException {
191200
// write out tag table
192201
int classTableSize = 0;
193202
int classNum = classes.keySet().size();
194-
int aliasSize = ((int) FastMath.log(classNum, 256) + 1); // make all
195-
// aliases a
196-
// fixed width
203+
int aliasSize = ((int) FastMath.log(classNum, 256) + 1); // make all aliases a fixed width
197204

198205
os.write(ByteUtils.convertToBytes(classNum)); // 3. "number of classes"
199206
for (String key : classes.keySet()) {
200207
BinaryClassObject bco = classes.get(key);
201208

202209
// write alias
203-
byte[] aliasBytes = fixClassAlias(bco.alias,
204-
aliasSize);
210+
byte[] aliasBytes = fixClassAlias(bco.alias, aliasSize);
205211
os.write(aliasBytes); // 4. "class alias"
206212
classTableSize += aliasSize;
207213

208214
// jME3 NEW: Write class hierarchy version numbers
209-
os.write( bco.classHierarchyVersions.length );
210-
for (int version : bco.classHierarchyVersions){
215+
os.write(bco.classHierarchyVersions.length);
216+
for (int version : bco.classHierarchyVersions) {
211217
os.write(ByteUtils.convertToBytes(version));
212218
}
213219
classTableSize += 1 + bco.classHierarchyVersions.length * 4;
214220

215-
// write classname size & classname
221+
// write class name size & class name
216222
byte[] classBytes = key.getBytes();
217223
os.write(ByteUtils.convertToBytes(classBytes.length)); // 5. "full class-name size"
218224
os.write(classBytes); // 6. "full class name"
@@ -236,14 +242,12 @@ public void save(Savable object, OutputStream os) throws IOException {
236242
// write out data to a separate stream
237243
int location = 0;
238244
// keep track of location for each piece
239-
HashMap<String, ArrayList<BinaryIdContentPair>> alreadySaved = new HashMap<>(
240-
contentTable.size());
245+
HashMap<String, ArrayList<BinaryIdContentPair>> alreadySaved = new HashMap<>(contentTable.size());
241246
for (Savable savable : contentKeys) {
242247
// look back at previous written data for matches
243248
String savableName = savable.getClass().getName();
244249
BinaryIdContentPair pair = contentTable.get(savable);
245-
ArrayList<BinaryIdContentPair> bucket = alreadySaved
246-
.get(savableName + getChunk(pair));
250+
ArrayList<BinaryIdContentPair> bucket = alreadySaved.get(savableName + getChunk(pair));
247251
int prevLoc = findPrevMatch(pair, bucket);
248252
if (prevLoc != -1) {
249253
locationTable.put(pair.getId(), prevLoc);
@@ -286,17 +290,14 @@ public void save(Savable object, OutputStream os) throws IOException {
286290
// append stream to the output stream
287291
out.writeTo(os);
288292

289-
290-
out = null;
291-
os = null;
292-
293293
if (debug) {
294-
logger.fine("Stats:");
295-
logger.log(Level.FINE, "classes: {0}", classNum);
296-
logger.log(Level.FINE, "class table: {0} bytes", classTableSize);
297-
logger.log(Level.FINE, "objects: {0}", numLocations);
298-
logger.log(Level.FINE, "location table: {0} bytes", locationTableSize);
299-
logger.log(Level.FINE, "data: {0} bytes", location);
294+
logger.log(Level.INFO, "BinaryExporter Stats:"
295+
+ "\n * Classes: {0}"
296+
+ "\n * Class Table: {1} bytes"
297+
+ "\n * Objects: {2}"
298+
+ "\n * Location Table: {3} bytes"
299+
+ "\n * Data: {4} bytes",
300+
new Object[] {classNum, classTableSize, numLocations, locationTableSize, location});
300301
}
301302
}
302303

@@ -305,14 +306,15 @@ private String getChunk(BinaryIdContentPair pair) {
305306
.getContent().bytes.length));
306307
}
307308

308-
private int findPrevMatch(BinaryIdContentPair oldPair,
309-
ArrayList<BinaryIdContentPair> bucket) {
310-
if (bucket == null)
309+
private int findPrevMatch(BinaryIdContentPair oldPair, ArrayList<BinaryIdContentPair> bucket) {
310+
if (bucket == null) {
311311
return -1;
312+
}
312313
for (int x = bucket.size(); --x >= 0;) {
313314
BinaryIdContentPair pair = bucket.get(x);
314-
if (pair.getContent().equals(oldPair.getContent()))
315+
if (pair.getContent().equals(oldPair.getContent())) {
315316
return locationTable.get(pair.getId());
317+
}
316318
}
317319
return -1;
318320
}
@@ -345,7 +347,7 @@ public OutputCapsule getCapsule(Savable object) {
345347
return contentTable.get(object).getContent();
346348
}
347349

348-
private BinaryClassObject createClassObject(Class<? extends Savable> clazz) throws IOException{
350+
private BinaryClassObject createClassObject(Class<? extends Savable> clazz) throws IOException {
349351
BinaryClassObject bco = new BinaryClassObject();
350352
bco.alias = generateTag();
351353
bco.nameFields = new HashMap<>();
@@ -361,10 +363,10 @@ public int processBinarySavable(Savable object) throws IOException {
361363
return -1;
362364
}
363365
Class<? extends Savable> clazz = object.getClass();
364-
BinaryClassObject bco = classes.get(object.getClass().getName());
366+
BinaryClassObject bco = classes.get(clazz.getName());
365367
// is this class been looked at before? in tagTable?
366368
if (bco == null) {
367-
bco = createClassObject(object.getClass());
369+
bco = createClassObject(clazz);
368370
}
369371

370372
// is object in contentTable?
@@ -379,7 +381,6 @@ public int processBinarySavable(Savable object) throws IOException {
379381
object.write(this);
380382
newPair.getContent().finish();
381383
return newPair.getId();
382-
383384
}
384385

385386
protected byte[] generateTag() {
@@ -401,4 +402,4 @@ private BinaryIdContentPair generateIdContentPair(BinaryClassObject bco) {
401402
new BinaryOutputCapsule(this, bco));
402403
return pair;
403404
}
404-
}
405+
}

0 commit comments

Comments
 (0)