8000 Tweak AbiUsageImpl serialization to take up less space · sakerbuild/saker.java.compiler@7c0e2e1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7c0e2e1

Browse files
committed
Tweak AbiUsageImpl serialization to take up less space
1 parent ee13b20 commit 7c0e2e1

File tree

1 file changed

+98
-16
lines changed

1 file changed

+98
-16
lines changed

impl/src/main/saker/java/compiler/impl/compile/handler/usage/AbiUsageImpl.java

Lines changed: 98 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919
import java.io.IOException;
2020
import java.io.ObjectInput;
2121
import java.io.ObjectOutput;
22+
import java.util.Map.Entry;
2223
import java.util.NavigableMap;
2324
import java.util.Objects;
2425
import java.util.TreeMap;
2526

26-
import saker.build.thirdparty.saker.util.io.SerialUtils;
27+
import saker.build.thirdparty.saker.util.ImmutableUtils;
2728

2829
public abstract class AbiUsageImpl implements Externalizable, AbiUsage {
2930
private static final long serialVersionUID = 1L;
@@ -266,36 +267,96 @@ public boolean isInheritesFromClass(String canonicalname) {
266267

267268
@Override
268269
public void writeExternal(ObjectOutput out) throws IOException {
269-
SerialUtils.writeExternalMap(out, referenceInfos, ObjectOutput::writeUTF, (o, info) -> info.writeExternal(o));
270+
if (referenceInfos == null) {
271+
out.writeInt(-1);
272+
return;
273+
}
274+
int size = referenceInfos.size();
275+
out.writeInt(size);
276+
byte[] flags = new byte[size];
277+
int i = 0;
278+
for (Entry<String, ReferenceInfo> entry : referenceInfos.entrySet()) {
279+
out.writeUTF(entry.getKey());
280+
flags[i++] = entry.getValue().getSerializationFlags();
281+
}
282+
283+
out.write(flags);
284+
i = 0;
285+
for (ReferenceInfo ri : referenceInfos.values()) {
286+
ri.writeForFlags(flags[i++], out);
287+
}
270288
}
271289

272290
@Override
273291
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
274-
referenceInfos = SerialUtils.readExternalSortedImmutableNavigableMap(in, ObjectInput::readUTF, i -> {
292+
int size = in.readInt();
293+
if (size < 0) {
294+
//nothing to read
295+
return;
296+
}
297+
byte[] flags = new byte[size];
298+
String[] names = new String[size];
299+
ReferenceInfo[] infos = new ReferenceInfo[size];
300+
301+
for (int i = 0; i < names.length; i++) {
302+
names[i] = in.readUTF();
303+
}
304+
305+
in.readFully(flags);
306+
307+
for (int i = 0; i < infos.length; i++) {
275308
ReferenceInfo ri = new ReferenceInfo();
276-
ri.readExternal(i);
277-
presentSimpleFlags |= ri.flags;
278-
return ri;
279-
});
309+
ri.readForFlags(flags[i], in);
310+
infos[i] = ri;
311+
312+
this.presentSimpleFlags |= ri.flags;
313+
}
314+
315+
this.referenceInfos = ImmutableUtils.unmodifiableNavigableMap(names, infos);
280316
}
281317

282318
protected static void writeStringByteMap(ObjectOutput out, NavigableMap<String, Byte> map) throws IOException {
283-
SerialUtils.writeExternalMap(out, map, ObjectOutput::writeUTF, (ObjectOutput o, Byte b) -> o.writeByte(b));
319+
//this serialization probably saves us some bytes in the output as we don't write the byte flags individually
320+
if (map == null) {
321+
out.writeInt(-1);
322+
return;
323+
}
324+
int size = map.size();
325+
out.writeInt(size);
326+
int i = 0;
327+
byte[] bytes = new byte[size];
328+
for (Entry<String, Byte> entry : map.entrySet()) {
329+
out.writeUTF(entry.getKey());
330+
bytes[i++] = entry.getValue();
331+
}
332+
out.write(bytes);
284333
}
285334

286-
protected static NavigableMap<String, Byte> readStringByteMap(ObjectInput in)
287-
throws ClassNotFoundException, IOException {
288-
return SerialUtils.readExternalSortedImmutableNavigableMap(in, ObjectInput::readUTF, i -> i.readByte());
335+
protected static NavigableMap<String, Byte> readStringByteMap(ObjectInput in) throws IOException {
336+
int size = in.readInt();
337+
if (size < 0) {
338+
return null;
339+
}
340+
String[] keys = new String[size];
341+
byte[] valbytes = new byte[size];
342+
for (int i = 0; i < keys.length; i++) {
343+
keys[i] = in.readUTF();
344+
}
345+
in.readFully(valbytes);
346+
Byte[] vals = new Byte[size];
347+
for (int i = 0; i < valbytes.length; i++) {
348+
vals[i] = valbytes[i];
349+
}
350+
351+
return ImmutableUtils.unmodifiableNavigableMap(keys, vals);
289352
}
290353

291354
@Override
292355
public String toString() {
293356
return getClass().getSimpleName() + "[" + referenceInfos + "]";
294357
}
295358

296-
private static final class ReferenceInfo implements Externalizable {
297-
private static final long serialVersionUID = 1L;
298-
359+
private static final class ReferenceInfo {
299360
protected byte flags;
300361
protected NavigableMap<String, Byte> memberFlags;
301362

@@ -324,7 +385,29 @@ public NavigableMap<String, Byte> getMemberFlagsCreate() {
324385
return map;
325386
}
326387

327-
@Override
388+
protected byte getSerializationFlags() {
389+
if (memberFlags == null) {
390+
return flags;
391+
}
392+
return (byte) (flags | FLAGS_RESERVED);
393+
}
394+
395+
protected void writeForFlags(byte flags, ObjectOutput out) throws IOException {
396+
if ((flags & FLAGS_RESERVED) != 0) {
397+
writeStringByteMap(out, memberFlags);
398+
}
399+
}
400+
401+
protected void readForFlags(byte flags, ObjectInput in) throws IOException {
402+
if ((flags & FLAGS_RESERVED) != 0) {
403+
this.flags = (byte) (flags & ~FLAGS_RESERVED);
404+
memberFlags = readStringByteMap(in);
405+
} else {
406+
this.flags = flags;
407+
}
408+
409+
}
410+
328411
public void writeExternal(ObjectOutput out) throws IOException {
329412
if (memberFlags == null) {
330413
//use the reserved flag to convey the presence of the member map, this lets us write a few bytes less to the output
@@ -335,7 +418,6 @@ public void writeExternal(ObjectOutput out) throws IOException {
335418
}
336419
}
337420

338-
@Override
339421
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
340422
flags = in.readByte();
341423
if ((flags & FLAGS_RESERVED) != 0) {

0 commit comments

Comments
 (0)
0