1 package org.matsim.utils.eventsfilecomparison;
3 import it.unimi.dsi.fastutil.floats.FloatArrayList;
4 import it.unimi.dsi.fastutil.floats.FloatList;
5 import it.unimi.dsi.fastutil.objects.Object2IntMap;
6 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
9 import java.io.DataInputStream;
10 import java.io.DataOutputStream;
11 import java.io.IOException;
12 import java.io.UncheckedIOException;
13 import java.nio.charset.StandardCharsets;
14 import java.security.MessageDigest;
15 import java.security.NoSuchAlgorithmException;
16 import java.util.Arrays;
35 static final int HEADER_V1 = 0x46502f31;
37 final FloatList timeArray;
38 final Object2IntMap<String> eventTypeCounter;
46 private EventFingerprint(FloatList timeArray, Object2IntMap<String> eventTypeCounter, byte[] hash) {
47 this.timeArray = timeArray;
48 this.eventTypeCounter = eventTypeCounter;
54 this.timeArray =
new FloatArrayList();
55 this.eventTypeCounter =
new Object2IntOpenHashMap<>();
56 this.hash =
new byte[20];
59 digest = MessageDigest.getInstance(
"SHA-1");
60 }
catch (NoSuchAlgorithmException e) {
61 throw new IllegalStateException(
"Hashing not supported;");
71 dataOutputStream.writeInt(eventFingerprint.timeArray.size());
72 for (
float time : eventFingerprint.timeArray) {
73 dataOutputStream.writeFloat(time);
77 dataOutputStream.writeInt(eventFingerprint.eventTypeCounter.size());
78 for (Map.Entry<String, Integer> entry : eventFingerprint.eventTypeCounter.entrySet()) {
79 dataOutputStream.writeUTF(entry.getKey());
80 dataOutputStream.writeInt(entry.getValue());
84 assert !Arrays.equals(eventFingerprint.hash,
new byte[20]) :
"Hash was not computed";
87 dataOutputStream.write(eventFingerprint.hash);
89 }
catch (IOException e) {
90 throw new UncheckedIOException(e);
99 int fileHeader = dataInputStream.readInt();
102 throw new IllegalArgumentException(
"Invalid fingerprint file header");
106 int timeArraySize = dataInputStream.readInt();
107 FloatList timeArray =
new FloatArrayList();
108 for (
int i = 0; i < timeArraySize; i++) {
109 timeArray.add(dataInputStream.readFloat());
113 int eventTypeCounterSize = dataInputStream.readInt();
114 Object2IntMap<String> eventTypeCounter =
new Object2IntOpenHashMap<>();
115 for (
int i = 0; i < eventTypeCounterSize; i++) {
116 String eventType = dataInputStream.readUTF();
117 int count = dataInputStream.readInt();
118 eventTypeCounter.put(eventType, count);
122 byte[] hash = dataInputStream.readNBytes(20);
128 return eventFingerprint;
131 void addTimeStamp(
double timestamp) {
132 timeArray.add((
float) timestamp);
135 void addEventType(String str) {
137 eventTypeCounter.mergeInt(str, 1, Integer::sum);
140 void addHashCode(String stringToAdd) {
141 if (stringToAdd == null) {
145 digest.update(stringToAdd.getBytes(StandardCharsets.UTF_8));
148 byte[] computeHash() {
149 if (this.digest == null)
150 throw new IllegalStateException(
"Hash was from from input and can not be computed");
152 byte[] digest = this.digest.digest();
153 System.arraycopy(digest, 0, hash, 0, hash.length);
159 return "EventFingerprint{" +
160 "timeArray=" + timeArray.size() +
161 ", eventTypeCounter=" + eventTypeCounter +
162 ", hash=" + Arrays.toString(hash) +
EventFingerprint(FloatList timeArray, Object2IntMap< String > eventTypeCounter, byte[] hash)
static InputStream getInputStream(URL url)
static URL getFileUrl(String filename)
static OutputStream getOutputStream(URL url, boolean append)
final MessageDigest digest
static EventFingerprint read(String fingerprintPath)
static void write(String filePath, EventFingerprint eventFingerprint)