• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gephi / graphstore / #570

17 Aug 2026 06:29PM UTC coverage: 91.198% (-0.04%) from 91.242%
#570

push

web-flow
Harden serialization: fail on unknown tags, fix char encoding (#284)

* Harden serialization: fail on unknown tags, fix char encoding

Three scoped fixes to the serialization layer. No change to the on-disk
format, so no VERSION bump.

- deserialize() silently returned null for an unrecognized type tag,
  surfacing later as a confusing ClassCastException or silent data loss.
  It now throws IOException naming the tag. The preceding `case -1` was
  unreachable (readUnsignedByte never returns -1) and is removed.

- CHAR and CHAR_ARRAY relied on DataOutput.writeChar/readChar, but
  DataInputOutput implements those with 4 bytes instead of the 2 the
  interface specifies. Production writes via DataOutputStream, so no
  stored data is affected, but graphstore's own tests were round-tripping
  an encoding that never reaches disk. Both sides now use
  writeShort/readUnsignedShort, which is byte-identical to
  DataOutputStream.writeChar, and DataInputOutput.writeChar/readChar are
  fixed to honour the contract.

- Dropped Locale support. Locale is not an AttributeUtils supported type,
  so it cannot enter a graph through the public API. Tag 124 is kept
  reserved so it is never reused.

Adds a test asserting all serialization tag constants are distinct.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Cover non-ASCII chars in serialization tests

The char tests only used ASCII values, so they could not detect a
narrowing of the 2-byte encoding. Extend them across the boundaries of
the 16-bit range: above 0x7F, above 0x7FF, either side of the
signed-short flip, the 16-bit maximum, and an unpaired surrogate.

Verified by temporarily narrowing CHAR to a symmetric 1-byte encoding,
which the previous values did not catch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

4 of 7 new or added lines in 2 files covered. (57.14%)

4 existing lines in 1 file now uncovered.

11791 of 12929 relevant lines covered (91.2%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.85
/src/main/java/org/gephi/graph/impl/Serialization.java
1
/*
2
 * Copyright 2012-2013 Gephi Consortium
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
 * use this file except in compliance with the License. You may obtain a copy of
6
 * the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 * License for the specific language governing permissions and limitations under
14
 * the License.
15
 */
16
package org.gephi.graph.impl;
17

18
import java.util.BitSet;
19
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
20
import it.unimi.dsi.fastutil.booleans.BooleanOpenHashSet;
21
import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap;
22
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
23
import it.unimi.dsi.fastutil.bytes.ByteOpenHashSet;
24
import it.unimi.dsi.fastutil.chars.Char2ObjectOpenHashMap;
25
import it.unimi.dsi.fastutil.chars.CharArrayList;
26
import it.unimi.dsi.fastutil.chars.CharOpenHashSet;
27
import it.unimi.dsi.fastutil.doubles.Double2IntMap;
28
import it.unimi.dsi.fastutil.doubles.Double2ObjectOpenHashMap;
29
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
30
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
31
import it.unimi.dsi.fastutil.floats.Float2ObjectOpenHashMap;
32
import it.unimi.dsi.fastutil.floats.FloatArrayList;
33
import it.unimi.dsi.fastutil.floats.FloatOpenHashSet;
34
import it.unimi.dsi.fastutil.ints.Int2IntMap;
35
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
36
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
37
import it.unimi.dsi.fastutil.ints.IntArrayList;
38
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
39
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
40
import it.unimi.dsi.fastutil.longs.LongArrayList;
41
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
42
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
43
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
44
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
45
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
46
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
47
import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet;
48
import java.io.DataInput;
49
import java.io.DataOutput;
50
import java.io.EOFException;
51
import java.io.IOException;
52
import java.lang.reflect.Array;
53
import java.math.BigDecimal;
54
import java.math.BigInteger;
55
import java.time.Instant;
56
import java.time.ZoneId;
57
import java.util.Date;
58
import java.util.List;
59
import java.util.Map;
60
import java.util.Set;
61
import org.gephi.graph.api.Configuration;
62
import org.gephi.graph.api.Edge;
63
import org.gephi.graph.api.Estimator;
64
import org.gephi.graph.api.GraphModel;
65
import org.gephi.graph.api.Interval;
66
import org.gephi.graph.api.Node;
67
import org.gephi.graph.api.Origin;
68
import org.gephi.graph.api.TimeFormat;
69
import org.gephi.graph.api.TimeRepresentation;
70
import org.gephi.graph.api.types.IntervalBooleanMap;
71
import org.gephi.graph.api.types.IntervalByteMap;
72
import org.gephi.graph.api.types.IntervalCharMap;
73
import org.gephi.graph.api.types.IntervalDoubleMap;
74
import org.gephi.graph.api.types.IntervalFloatMap;
75
import org.gephi.graph.api.types.IntervalIntegerMap;
76
import org.gephi.graph.api.types.IntervalLongMap;
77
import org.gephi.graph.api.types.IntervalMap;
78
import org.gephi.graph.api.types.IntervalSet;
79
import org.gephi.graph.api.types.IntervalShortMap;
80
import org.gephi.graph.api.types.IntervalStringMap;
81
import org.gephi.graph.api.types.TimestampBooleanMap;
82
import org.gephi.graph.api.types.TimestampByteMap;
83
import org.gephi.graph.api.types.TimestampCharMap;
84
import org.gephi.graph.api.types.TimestampDoubleMap;
85
import org.gephi.graph.api.types.TimestampFloatMap;
86
import org.gephi.graph.api.types.TimestampIntegerMap;
87
import org.gephi.graph.api.types.TimestampLongMap;
88
import org.gephi.graph.api.types.TimestampMap;
89
import org.gephi.graph.api.types.TimestampSet;
90
import org.gephi.graph.api.types.TimestampShortMap;
91
import org.gephi.graph.api.types.TimestampStringMap;
92
import org.gephi.graph.impl.EdgeImpl.EdgePropertiesImpl;
93
import org.gephi.graph.impl.NodeImpl.NodePropertiesImpl;
94
import org.gephi.graph.impl.utils.DataInputOutput;
95
import org.gephi.graph.impl.utils.LongPacker;
96

97
// Greatly inspired from JDBM https://github.com/jankotek/JDBM3
98
public class Serialization {
99

100
    final static float VERSION = 0.5f;
101
    final static int NULL_ID = -1;
102
    final static int NULL = 0;
103
    final static int NORMAL = 1;
104
    final static int BOOLEAN_TRUE = 2;
105
    final static int BOOLEAN_FALSE = 3;
106
    final static int INTEGER_MINUS_1 = 4;
107
    final static int INTEGER_0 = 5;
108
    final static int INTEGER_1 = 6;
109
    final static int INTEGER_2 = 7;
110
    final static int INTEGER_3 = 8;
111
    final static int INTEGER_4 = 9;
112
    final static int INTEGER_5 = 10;
113
    final static int INTEGER_6 = 11;
114
    final static int INTEGER_7 = 12;
115
    final static int INTEGER_8 = 13;
116
    final static int INTEGER_255 = 14;
117
    final static int INTEGER_PACK_NEG = 15;
118
    final static int INTEGER_PACK = 16;
119
    final static int LONG_MINUS_1 = 17;
120
    final static int LONG_0 = 18;
121
    final static int LONG_1 = 19;
122
    final static int LONG_2 = 20;
123
    final static int LONG_3 = 21;
124
    final static int LONG_4 = 22;
125
    final static int LONG_5 = 23;
126
    final static int LONG_6 = 24;
127
    final static int LONG_7 = 25;
128
    final static int LONG_8 = 26;
129
    final static int LONG_PACK_NEG = 27;
130
    final static int LONG_PACK = 28;
131
    final static int LONG_255 = 29;
132
    final static int LONG_MINUS_MAX = 30;
133
    final static int SHORT_MINUS_1 = 31;
134
    final static int SHORT_0 = 32;
135
    final static int SHORT_1 = 33;
136
    final static int SHORT_255 = 34;
137
    final static int SHORT_FULL = 35;
138
    final static int BYTE_MINUS_1 = 36;
139
    final static int BYTE_0 = 37;
140
    final static int BYTE_1 = 38;
141
    final static int BYTE_FULL = 39;
142
    final static int CHAR = 40;
143
    final static int FLOAT_MINUS_1 = 41;
144
    final static int FLOAT_0 = 42;
145
    final static int FLOAT_1 = 43;
146
    final static int FLOAT_255 = 44;
147
    final static int FLOAT_SHORT = 45;
148
    final static int FLOAT_FULL = 46;
149
    final static int DOUBLE_MINUS_1 = 47;
150
    final static int DOUBLE_0 = 48;
151
    final static int DOUBLE_1 = 49;
152
    final static int DOUBLE_255 = 50;
153
    final static int DOUBLE_SHORT = 51;
154
    final static int DOUBLE_FULL = 52;
155
    final static int DOUBLE_ARRAY = 53;
156
    final static int BIGDECIMAL = 54;
157
    final static int BIGINTEGER = 55;
158
    final static int FLOAT_ARRAY = 56;
159
    final static int INTEGER_MINUS_MAX = 57;
160
    final static int SHORT_ARRAY = 58;
161
    final static int BOOLEAN_ARRAY = 59;
162
    final static int ARRAY_INT_B_255 = 60;
163
    final static int ARRAY_INT_B_INT = 61;
164
    final static int ARRAY_INT_S = 62;
165
    final static int ARRAY_INT_I = 63;
166
    final static int ARRAY_INT_PACKED = 64;
167
    final static int ARRAY_LONG_B = 65;
168
    final static int ARRAY_LONG_S = 66;
169
    final static int ARRAY_LONG_I = 67;
170
    final static int ARRAY_LONG_L = 68;
171
    final static int ARRAY_LONG_PACKED = 69;
172
    final static int CHAR_ARRAY = 70;
173
    final static int ARRAY_BYTE_INT = 71;
174
    final static int NOTUSED_ARRAY_OBJECT_255 = 72;
175
    final static int ARRAY_OBJECT = 73;
176
    final static int STRING_ARRAY = 74;
177
    final static int STRING_EMPTY = 101;
178
    final static int NOTUSED_STRING_255 = 102;
179
    final static int STRING = 103;
180
    // Reserved, do not reuse: was java.util.Locale, removed because Locale isn't an
181
    // AttributeUtils supported type. Kept so old streams can still be identified.
182
    final static int LOCALE = 124;
183
    final static int PROPERTIES = 125;
184
    final static int CLASS = 126;
185
    final static int DATE = 127;
186
    final static String EMPTY_STRING = "";
187
    // Specifics
188
    final static int NODE = 200;
189
    final static int EDGE = 201;
190
    final static int EDGETYPE_STORE = 202;
191
    final static int COLUMN_ORIGIN = 203;
192
    final static int TABLE = 204;
193
    final static int CONFIGURATION = 205;
194
    final static int GRAPH_STORE = 206;
195
    final static int GRAPH_FACTORY = 207;
196
    final static int GRAPH_VIEW_STORE = 208;
197
    final static int GRAPH_VIEW = 209;
198
    final static int BIT_VECTOR = 210;
199
    final static int GRAPH_STORE_CONFIGURATION = 211;
200
    final static int TIME_REPRESENTATION = 212;
201
    final static int GRAPH_VERSION = 213;
202
    final static int NODE_PROPERTIES = 214;
203
    final static int EDGE_PROPERTIES = 215;
204
    final static int TEXT_PROPERTIES = 216;
205
    final static int ESTIMATOR = 217;
206
    final static int GRAPH_ATTRIBUTES = 218;
207
    final static int TIMESTAMP_INDEX_STORE = 219;
208
    final static int INTERVAL_INDEX_STORE = 220;
209
    final static int TIME_FORMAT = 221;
210
    final static int TIME_STORE = 222;
211
    final static int TIMESTAMP_SET = 223;
212
    final static int INTERVAL_SET = 224;
213
    final static int TIMESTAMP_MAP = 225;
214
    final static int INTERVAL_MAP = 226;
215
    final static int TIME_ZONE = 227;
216
    final static int INTERVAL = 228;
217
    final static int LIST = 229;
218
    final static int SET = 230;
219
    final static int MAP = 231;
220
    final static int INSTANT = 232;
221
    // Store
222
    protected final Int2IntMap idMap;
223
    protected GraphModelImpl model;
224
    protected float readVersion = VERSION;
1✔
225
    // Deserialized configuration
226
    protected GraphStoreConfigurationVersion graphStoreConfigurationVersion;
227

228
    public Serialization() {
229
        this(null);
1✔
230
    }
1✔
231

232
    public Serialization(GraphModelImpl graphModel) {
1✔
233
        model = graphModel;
1✔
234
        idMap = new Int2IntOpenHashMap();
1✔
235
        idMap.defaultReturnValue(NULL_ID);
1✔
236
    }
1✔
237

238
    public void serializeGraphModel(DataOutput out, GraphModelImpl model) throws IOException {
239
        this.model = model;
1✔
240
        serialize(out, VERSION);
1✔
241
        serialize(out, model.configuration);
1✔
242
        serialize(out, model.store);
1✔
243
    }
1✔
244

245
    public GraphModelImpl deserializeGraphModel(DataInput is) throws IOException, ClassNotFoundException {
246
        readVersion = (Float) deserialize(is);
1✔
247
        ConfigurationImpl config = (ConfigurationImpl) deserialize(is);
1✔
248
        model = new GraphModelImpl(config.toConfiguration());
1✔
249
        deserialize(is);
1✔
250
        return model;
1✔
251
    }
252

253
    public GraphModelImpl deserializeGraphModel(DataInput is, GraphModel graphModel) throws IOException, ClassNotFoundException {
254
        model = (GraphModelImpl) graphModel;
1✔
255
        readVersion = (Float) deserialize(is);
1✔
256
        ConfigurationImpl config = (ConfigurationImpl) deserialize(is);
1✔
257
        verifyCompatibility(config, model.configuration);
1✔
258
        deserialize(is);
1✔
259
        return model;
1✔
260
    }
261

262
    private void verifyCompatibility(ConfigurationImpl readConfig, ConfigurationImpl modelConfig) {
263
        // Time representation
264
        if (!readConfig.getTimeRepresentation().equals(modelConfig.getTimeRepresentation())) {
1✔
265
            throw new RuntimeException("The time representations doesn't match, read: " + readConfig
×
266
                    .getTimeRepresentation() + ", model: " + modelConfig.getTimeRepresentation());
×
267
        }
268

269
        // Node id type
270
        if (!readConfig.getNodeIdType().equals(modelConfig.getNodeIdType())) {
1✔
271
            throw new RuntimeException("The node id type doesn't match, read: " + readConfig
×
272
                    .getNodeIdType() + ", model: " + modelConfig.getNodeIdType());
×
273
        }
274

275
        // Edge id type
276
        if (!readConfig.getEdgeIdType().equals(modelConfig.getEdgeIdType())) {
1✔
277
            throw new RuntimeException("The edge id type doesn't match, read: " + readConfig
×
278
                    .getEdgeIdType() + ", model: " + modelConfig.getEdgeIdType());
×
279
        }
280

281
        // Edge weight type
282
        if (!readConfig.getEdgeWeightType().equals(modelConfig.getEdgeWeightType())) {
1✔
283
            throw new RuntimeException("The edge weight type doesn't match, read: " + readConfig
×
284
                    .getEdgeWeightType() + ", model: " + modelConfig.getEdgeWeightType());
×
285
        }
286

287
        // Edge label type
288
        if (!readConfig.getEdgeLabelType().equals(modelConfig.getEdgeLabelType())) {
1✔
289
            throw new RuntimeException("The edge label type doesn't match, read: " + readConfig
×
290
                    .getEdgeLabelType() + ", model: " + modelConfig.getEdgeLabelType());
×
291
        }
292
    }
1✔
293

294
    public GraphModelImpl deserializeGraphModelWithoutVersionPrefix(DataInput is, float version) throws IOException, ClassNotFoundException {
295
        readVersion = version;
1✔
296
        ConfigurationImpl config = (ConfigurationImpl) deserialize(is);
1✔
297
        model = new GraphModelImpl(config.toConfiguration());
1✔
298
        deserialize(is);
1✔
299
        return model;
1✔
300
    }
301

302
    public void serializeGraphStore(DataOutput out, GraphStore store) throws IOException {
303
        // Configuration
304
        serializeGraphStoreConfiguration(out);
1✔
305

306
        // GraphVersion
307
        serialize(out, store.version);
1✔
308

309
        // Edge types
310
        EdgeTypeStore edgeTypeStore = store.edgeTypeStore;
1✔
311
        serialize(out, edgeTypeStore);
1✔
312

313
        // Column
314
        serialize(out, store.nodeTable);
1✔
315
        serialize(out, store.edgeTable);
1✔
316

317
        // Time store
318
        serialize(out, store.timeStore);
1✔
319

320
        // Factory
321
        serialize(out, store.factory);
1✔
322

323
        // Atts
324
        serialize(out, store.attributes);
1✔
325

326
        // TimeFormat
327
        serialize(out, store.timeFormat);
1✔
328

329
        // Time zone
330
        serialize(out, store.timeZone);
1✔
331

332
        // Nodes + Edges
333
        int nodesAndEdges = store.nodeStore.size() + store.edgeStore.size();
1✔
334
        serialize(out, nodesAndEdges);
1✔
335

336
        for (Node node : store.nodeStore) {
1✔
337
            serialize(out, node);
1✔
338
        }
1✔
339
        for (Edge edge : store.edgeStore) {
1✔
340
            serialize(out, edge);
1✔
341
        }
1✔
342

343
        // Views
344
        serialize(out, store.viewStore);
1✔
345
    }
1✔
346

347
    public GraphStore deserializeGraphStore(DataInput is) throws IOException, ClassNotFoundException {
348
        if (!model.store.nodeStore.isEmpty()) { // TODO test other stores
1✔
349
            throw new IOException("The store is not empty");
×
350
        }
351

352
        idMap.clear();
1✔
353

354
        // Store Configuration
355
        deserialize(is);
1✔
356

357
        // Graph Version
358
        GraphVersion version = (GraphVersion) deserialize(is);
1✔
359
        model.store.version.nodeVersion = version.nodeVersion;
1✔
360
        model.store.version.edgeVersion = version.edgeVersion;
1✔
361

362
        // Edge types
363
        deserialize(is);
1✔
364

365
        // Columns
366
        deserialize(is);
1✔
367
        deserialize(is);
1✔
368

369
        // Time store
370
        deserialize(is);
1✔
371

372
        // Factory
373
        deserialize(is);
1✔
374

375
        // Atts
376
        GraphAttributesImpl attributes = (GraphAttributesImpl) deserialize(is);
1✔
377
        model.store.attributes.setGraphAttributes(attributes);
1✔
378

379
        // TimeFormat
380
        deserialize(is);
1✔
381

382
        // Time zone
383
        deserialize(is);
1✔
384

385
        // Nodes and edges
386
        int nodesAndEdges = (Integer) deserialize(is);
1✔
387
        for (int i = 0; i < nodesAndEdges; i++) {
1✔
388
            deserialize(is);
1✔
389
        }
390

391
        // ViewStore
392
        deserialize(is);
1✔
393

394
        return model.store;
1✔
395
    }
396

397
    private void serializeNode(DataOutput out, NodeImpl node) throws IOException {
398
        serialize(out, node.getId());
1✔
399
        serialize(out, node.storeId);
1✔
400
        serialize(out, node.attributes.attributes);
1✔
401
        serialize(out, node.properties);
1✔
402
    }
1✔
403

404
    private void serializeEdge(DataOutput out, EdgeImpl edge) throws IOException {
405
        serialize(out, edge.getId());
1✔
406
        serialize(out, edge.source.storeId);
1✔
407
        serialize(out, edge.target.storeId);
1✔
408
        serialize(out, edge.type);
1✔
409
        if (edge.graphStore != null && edge.hasDynamicWeight()) {
1✔
410
            serialize(out, edge.getWeight());
×
411
        } else {
412
            serialize(out, GraphStoreConfiguration.DEFAULT_EDGE_WEIGHT);
1✔
413
        }
414
        serialize(out, edge.isDirected());
1✔
415
        serialize(out, edge.attributes.attributes);
1✔
416
        serialize(out, edge.properties);
1✔
417
    }
1✔
418

419
    private NodeImpl deserializeNode(DataInput is) throws IOException, ClassNotFoundException {
420
        Object id = deserialize(is);
1✔
421
        int storeId = (Integer) deserialize(is);
1✔
422
        Object[] attributes = (Object[]) deserialize(is);
1✔
423
        NodePropertiesImpl properties = (NodePropertiesImpl) deserialize(is);
1✔
424

425
        NodeImpl node = (NodeImpl) model.store.factory.newNode(id);
1✔
426
        node.attributes.setBackingArray(attributes);
1✔
427
        if (node.properties != null) {
1✔
428
            node.setNodeProperties(properties);
1✔
429
        }
430
        model.store.nodeStore.add(node);
1✔
431

432
        idMap.put(storeId, node.storeId);
1✔
433

434
        return node;
1✔
435
    }
436

437
    private EdgeImpl deserializeEdge(DataInput is) throws IOException, ClassNotFoundException {
438
        Object id = deserialize(is);
1✔
439
        int sourceId = (Integer) deserialize(is);
1✔
440
        int targetId = (Integer) deserialize(is);
1✔
441
        int type = (Integer) deserialize(is);
1✔
442
        double weight = (Double) deserialize(is);
1✔
443
        boolean directed = (Boolean) deserialize(is);
1✔
444
        Object[] attributes = (Object[]) deserialize(is);
1✔
445
        EdgePropertiesImpl properties = (EdgePropertiesImpl) deserialize(is);
1✔
446

447
        int sourceNewId = idMap.get(sourceId);
1✔
448
        int targetNewId = idMap.get(targetId);
1✔
449

450
        if (sourceNewId == NULL_ID || targetNewId == NULL_ID) {
1✔
451
            throw new IOException("The edge source or target can't be found");
×
452
        }
453

454
        NodeImpl source = model.store.nodeStore.get(sourceNewId);
1✔
455
        NodeImpl target = model.store.nodeStore.get(targetNewId);
1✔
456

457
        EdgeImpl edge = (EdgeImpl) model.store.factory.newEdge(id, source, target, type, weight, directed);
1✔
458
        edge.attributes.setBackingArray(attributes);
1✔
459
        if (edge.properties != null) {
1✔
460
            edge.setEdgeProperties(properties);
1✔
461
        }
462

463
        model.store.edgeStore.add(edge);
1✔
464

465
        return edge;
1✔
466
    }
467

468
    private void serializeEdgeTypeStore(final DataOutput out) throws IOException {
469
        EdgeTypeStore edgeTypeStore = model.store.edgeTypeStore;
1✔
470
        int length = edgeTypeStore.length;
1✔
471
        serialize(out, length);
1✔
472
        short[] ids = edgeTypeStore.getIds();
1✔
473
        serialize(out, ids);
1✔
474
        Object[] labels = edgeTypeStore.getLabels();
1✔
475
        serialize(out, labels);
1✔
476
        short[] garbage = edgeTypeStore.getGarbage();
1✔
477
        serialize(out, garbage);
1✔
478
    }
1✔
479

480
    private EdgeTypeStore deserializeEdgeTypeStore(final DataInput is) throws IOException, ClassNotFoundException {
481
        int length = (Integer) deserialize(is);
1✔
482
        short[] ids = (short[]) deserialize(is);
1✔
483
        Object[] labels = (Object[]) deserialize(is);
1✔
484
        short[] garbage = (short[]) deserialize(is);
1✔
485

486
        EdgeTypeStore edgeTypeStore = model.store.edgeTypeStore;
1✔
487
        edgeTypeStore.length = length;
1✔
488
        for (int i = 0; i < ids.length; i++) {
1✔
489
            short id = ids[i];
1✔
490
            Object label = labels[i];
1✔
491
            edgeTypeStore.idMap.put(id, label);
1✔
492
            edgeTypeStore.labelMap.put(label, id);
1✔
493
        }
494
        for (int i = 0; i < garbage.length; i++) {
1✔
495
            edgeTypeStore.garbageQueue.add(garbage[i]);
1✔
496
        }
497
        return edgeTypeStore;
1✔
498
    }
499

500
    private void serializeTable(final DataOutput out, final TableImpl table) throws IOException {
501
        serialize(out, table.store.elementType);
1✔
502

503
        serializeColumnStore(out, table.store);
1✔
504
    }
1✔
505

506
    private TableImpl deserializeTable(final DataInput is) throws IOException, ClassNotFoundException {
507
        Class elementType = (Class) deserialize(is);
1✔
508

509
        TableImpl table = null;
1✔
510

511
        if (elementType.equals(Node.class)) {
1✔
512
            table = model.store.nodeTable;
1✔
513
        } else if (elementType.equals(Edge.class)) {
1✔
514
            table = model.store.edgeTable;
1✔
515
        } else {
516
            throw new RuntimeException("Not recognized column store");
×
517
        }
518

519
        deserializeColumnStore(is, table);
1✔
520

521
        return table;
1✔
522
    }
523

524
    private void serializeColumnStore(final DataOutput out, final ColumnStore columnStore) throws IOException {
525
        int length = columnStore.length;
1✔
526
        serialize(out, length);
1✔
527

528
        for (int i = 0; i < length; i++) {
1✔
529
            ColumnImpl col = columnStore.columns[i];
1✔
530
            serializeColumn(out, col);
1✔
531
        }
532

533
        serialize(out, columnStore.garbageQueue.toShortArray());
1✔
534
    }
1✔
535

536
    private ColumnStore deserializeColumnStore(final DataInput is, final TableImpl table) throws IOException, ClassNotFoundException {
537
        ColumnStore columnStore = table.store;
1✔
538
        int length = (Integer) deserialize(is);
1✔
539
        columnStore.length = length;
1✔
540

541
        for (int i = 0; i < length; i++) {
1✔
542
            ColumnImpl col = (ColumnImpl) deserializeColumn(is, table);
1✔
543
            if (col != null) {
1✔
544
                columnStore.columns[col.storeId] = col;
1✔
545
                columnStore.idMap.put(col.id, columnStore.intToShort(col.storeId));
1✔
546
                if (columnStore.indexStore != null) {
1✔
547
                    columnStore.indexStore.addColumn(col);
1✔
548
                }
549
            }
550
        }
551

552
        short[] garbage = (short[]) deserialize(is);
1✔
553
        for (int i = 0; i < garbage.length; i++) {
1✔
554
            columnStore.garbageQueue.add(garbage[i]);
1✔
555
        }
556
        return columnStore;
1✔
557
    }
558

559
    private void serializeColumn(final DataOutput out, final ColumnImpl column) throws IOException {
560
        if (column == null) {
1✔
561
            serialize(out, null);
1✔
562
            return;
1✔
563
        }
564
        serialize(out, column.id);
1✔
565
        serialize(out, column.title);
1✔
566
        serialize(out, column.origin);
1✔
567
        serialize(out, column.storeId);
1✔
568
        serialize(out, column.typeClass);
1✔
569
        serialize(out, column.defaultValue);
1✔
570
        serialize(out, column.indexed);
1✔
571
        serialize(out, column.readOnly);
1✔
572
        serialize(out, column.estimator);
1✔
573
    }
1✔
574

575
    private ColumnImpl deserializeColumn(final DataInput is, TableImpl table) throws IOException, ClassNotFoundException {
576
        String id = (String) deserialize(is);
1✔
577
        if (id == null) {
1✔
578
            return null;
1✔
579
        }
580
        String title = (String) deserialize(is);
1✔
581
        Origin origin = (Origin) deserialize(is);
1✔
582
        int storeId = (Integer) deserialize(is);
1✔
583
        Class typeClass = (Class) deserialize(is);
1✔
584
        Object defaultValue = deserialize(is);
1✔
585
        boolean indexed = (Boolean) deserialize(is);
1✔
586
        boolean readOnly = (Boolean) deserialize(is);
1✔
587
        Estimator estimator = (Estimator) deserialize(is);
1✔
588

589
        ColumnImpl column = model.store.defaultColumns.getColumn(table, storeId);
1✔
590
        if (column == null) {
1✔
591
            column = new ColumnImpl(table, (String) id, typeClass, title, defaultValue, origin, indexed, readOnly);
1✔
592
            column.storeId = storeId;
1✔
593
        }
594

595
        if (estimator != null) {
1✔
596
            column.setEstimator(estimator);
1✔
597
        }
598

599
        return column;
1✔
600
    }
601

602
    private void serializeGraphFactory(final DataOutput out) throws IOException {
603
        GraphFactoryImpl factory = model.store.factory;
1✔
604

605
        serialize(out, factory.getNodeCounter());
1✔
606
        serialize(out, factory.getEdgeCounter());
1✔
607
    }
1✔
608

609
    private GraphFactoryImpl deserializeGraphFactory(final DataInput is) throws IOException, ClassNotFoundException {
610
        GraphFactoryImpl graphFactory = model.store.factory;
1✔
611

612
        int nodeCounter = (Integer) deserialize(is);
1✔
613
        int edgeCounter = (Integer) deserialize(is);
1✔
614

615
        graphFactory.setNodeCounter(nodeCounter);
1✔
616
        graphFactory.setEdgeCounter(edgeCounter);
1✔
617

618
        return graphFactory;
1✔
619
    }
620

621
    private void serializeViewStore(final DataOutput out) throws IOException {
622
        GraphViewStore viewStore = model.store.viewStore;
1✔
623

624
        serialize(out, viewStore.length);
1✔
625
        serialize(out, viewStore.views);
1✔
626
        serialize(out, viewStore.garbageQueue.toIntArray());
1✔
627
    }
1✔
628

629
    private GraphViewStore deserializeViewStore(final DataInput is) throws IOException, ClassNotFoundException {
630
        GraphViewStore viewStore = model.store.viewStore;
1✔
631

632
        int length = (Integer) deserialize(is);
1✔
633
        Object[] views = (Object[]) deserialize(is);
1✔
634
        int[] garbages = (int[]) deserialize(is);
1✔
635

636
        viewStore.length = length;
1✔
637
        viewStore.views = new GraphViewImpl[views.length];
1✔
638
        System.arraycopy(views, 0, viewStore.views, 0, views.length);
1✔
639
        for (int i = 0; i < garbages.length; i++) {
1✔
640
            viewStore.garbageQueue.add(garbages[i]);
1✔
641
        }
642
        return viewStore;
1✔
643
    }
644

645
    private void serializeGraphView(final DataOutput out, final GraphViewImpl view) throws IOException {
646
        serialize(out, view.nodeView);
1✔
647
        serialize(out, view.edgeView);
1✔
648
        serialize(out, view.storeId);
1✔
649
        serialize(out, view.nodeCount);
1✔
650
        serialize(out, view.edgeCount);
1✔
651

652
        serialize(out, view.nodeBitVector);
1✔
653
        serialize(out, view.edgeBitVector);
1✔
654

655
        serialize(out, view.typeCounts);
1✔
656
        serialize(out, view.mutualEdgeTypeCounts);
1✔
657
        serialize(out, view.mutualEdgesCount);
1✔
658

659
        serialize(out, view.version);
1✔
660

661
        serialize(out, view.attributes);
1✔
662
        serialize(out, view.interval);
1✔
663
    }
1✔
664

665
    private GraphViewImpl deserializeGraphView(final DataInput is) throws IOException, ClassNotFoundException {
666
        boolean nodeView = (Boolean) deserialize(is);
1✔
667
        boolean edgeView = (Boolean) deserialize(is);
1✔
668
        GraphViewImpl view = new GraphViewImpl(model.store, nodeView, edgeView);
1✔
669

670
        int storeId = (Integer) deserialize(is);
1✔
671
        int nodeCount = (Integer) deserialize(is);
1✔
672
        int edgeCount = (Integer) deserialize(is);
1✔
673
        BitSet nodeCountVector = (BitSet) deserialize(is);
1✔
674
        BitSet edgeCountVector = (BitSet) deserialize(is);
1✔
675
        int[] typeCounts = (int[]) deserialize(is);
1✔
676
        int[] mutualEdgeTypeCounts = (int[]) deserialize(is);
1✔
677
        int mutualEdgesCount = (Integer) deserialize(is);
1✔
678
        GraphVersion version = (GraphVersion) deserialize(is);
1✔
679
        GraphAttributesImpl atts = (GraphAttributesImpl) deserialize(is);
1✔
680
        Interval interval = (Interval) deserialize(is);
1✔
681

682
        view.nodeCount = nodeCount;
1✔
683
        view.edgeCount = edgeCount;
1✔
684
        view.nodeBitVector = nodeCountVector;
1✔
685
        view.edgeBitVector = edgeCountVector;
1✔
686
        view.storeId = storeId;
1✔
687

688
        view.typeCounts = typeCounts;
1✔
689
        view.mutualEdgesCount = mutualEdgesCount;
1✔
690
        view.mutualEdgeTypeCounts = mutualEdgeTypeCounts;
1✔
691

692
        view.version.nodeVersion = version.nodeVersion;
1✔
693
        view.version.edgeVersion = version.edgeVersion;
1✔
694

695
        view.attributes.setGraphAttributes(atts);
1✔
696
        view.interval = interval;
1✔
697

698
        return view;
1✔
699
    }
700

701
    // Made compatible with legacy BitVector serialization, which was in place until
702
    // version 0.8.1
703
    public void serializeBitSet(final DataOutput out, final BitSet bitSet) throws IOException {
704
        // BitSet.length() returns the index of the highest set bit + 1
705
        // This gives us the logical size (0 if empty)
706
        int size = bitSet.length();
1✔
707

708
        serialize(out, size);
1✔
709

710
        // Get the long array from BitSet
711
        long[] words = bitSet.toLongArray();
1✔
712

713
        // Calculate how many longs BitVector would use for this size
714
        int requiredLongs = (size + 63) / 64;
1✔
715

716
        // Create array with the exact required size (matching BitVector format)
717
        long[] elements = new long[requiredLongs];
1✔
718

719
        // Copy the BitSet data
720
        System.arraycopy(words, 0, elements, 0, Math.min(words.length, requiredLongs));
1✔
721

722
        serialize(out, elements);
1✔
723
    }
1✔
724

725
    public BitSet deserializeBitSet(final DataInput is) throws IOException, ClassNotFoundException {
726
        int size = (Integer) deserialize(is);
1✔
727
        long[] elements = (long[]) deserialize(is);
1✔
728

729
        // BitSet.valueOf() handles the long array correctly
730
        return BitSet.valueOf(elements);
1✔
731
    }
732

733
    private void serializeGraphStoreConfiguration(final DataOutput out) throws IOException {
734
        out.write(GRAPH_STORE_CONFIGURATION);
1✔
735
        serialize(out, GraphStoreConfiguration.ENABLE_ELEMENT_LABEL);
1✔
736
        serialize(out, GraphStoreConfiguration.ENABLE_ELEMENT_TIME_SET);
1✔
737
        // Was GraphStoreConfiguration.ENABLE_NODE_PROPERTIES
738
        serialize(out, true);
1✔
739
        // Was GraphStoreConfiguration.ENABLE_EDGE_PROPERTIES
740
        serialize(out, true);
1✔
741
    }
1✔
742

743
    private GraphStoreConfigurationVersion deserializeGraphStoreConfiguration(final DataInput is) throws IOException, ClassNotFoundException {
744
        boolean enableElementLabel = (Boolean) deserialize(is);
1✔
745
        boolean enableElementTimestamp = (Boolean) deserialize(is);
1✔
746
        boolean enableNodeProperties = (Boolean) deserialize(is);
1✔
747
        boolean enableEdgeProperties = (Boolean) deserialize(is);
1✔
748

749
        graphStoreConfigurationVersion = new GraphStoreConfigurationVersion(enableElementLabel, enableElementTimestamp,
1✔
750
                enableNodeProperties, enableEdgeProperties);
751
        return graphStoreConfigurationVersion;
1✔
752
    }
753

754
    private void serializeGraphVersion(final DataOutput out, final GraphVersion graphVersion) throws IOException {
755
        serialize(out, graphVersion.nodeVersion);
1✔
756
        serialize(out, graphVersion.edgeVersion);
1✔
757
    }
1✔
758

759
    private GraphVersion deserializeGraphVersion(final DataInput is) throws IOException, ClassNotFoundException {
760
        GraphVersion graphVersion = new GraphVersion(null);
1✔
761

762
        int nodeVersion = (Integer) deserialize(is);
1✔
763
        int edgeVersion = (Integer) deserialize(is);
1✔
764

765
        graphVersion.nodeVersion = nodeVersion;
1✔
766
        graphVersion.edgeVersion = edgeVersion;
1✔
767

768
        return graphVersion;
1✔
769
    }
770

771
    private void serializeNodeProperties(final DataOutput out, final NodePropertiesImpl nodeProperties) throws IOException {
772
        serialize(out, nodeProperties.x);
1✔
773
        serialize(out, nodeProperties.y);
1✔
774
        serialize(out, nodeProperties.z);
1✔
775
        serialize(out, nodeProperties.rgba);
1✔
776
        serialize(out, nodeProperties.size);
1✔
777
        serialize(out, nodeProperties.fixed);
1✔
778
        serialize(out, nodeProperties.textProperties);
1✔
779
    }
1✔
780

781
    private NodePropertiesImpl deserializeNodeProperties(final DataInput is) throws IOException, ClassNotFoundException {
782
        float x = (Float) deserialize(is);
1✔
783
        float y = (Float) deserialize(is);
1✔
784
        float z = (Float) deserialize(is);
1✔
785
        int rgba = (Integer) deserialize(is);
1✔
786
        float size = (Float) deserialize(is);
1✔
787
        boolean fixed = (Boolean) deserialize(is);
1✔
788
        TextPropertiesImpl textProperties = (TextPropertiesImpl) deserialize(is);
1✔
789

790
        NodePropertiesImpl props = new NodePropertiesImpl();
1✔
791
        props.x = x;
1✔
792
        props.y = y;
1✔
793
        props.z = z;
1✔
794
        props.rgba = rgba;
1✔
795
        props.size = size;
1✔
796
        props.fixed = fixed;
1✔
797
        props.setTextProperties(textProperties);
1✔
798

799
        return props;
1✔
800
    }
801

802
    private void serializeEdgeProperties(final DataOutput out, final EdgePropertiesImpl edgeProperties) throws IOException {
803
        serialize(out, edgeProperties.rgba);
1✔
804
        serialize(out, edgeProperties.textProperties);
1✔
805
    }
1✔
806

807
    private EdgePropertiesImpl deserializeEdgeProperties(final DataInput is) throws IOException, ClassNotFoundException {
808
        int rgba = (Integer) deserialize(is);
1✔
809
        TextPropertiesImpl textProperties = (TextPropertiesImpl) deserialize(is);
1✔
810

811
        EdgePropertiesImpl props = new EdgePropertiesImpl();
1✔
812
        props.rgba = rgba;
1✔
813
        props.setTextProperties(textProperties);
1✔
814

815
        // Gephi versions before 0.11 used zero alpha to indicate that the element has
816
        // no color
817
        // Override this to avoid hidden elements
818
        if (props.alpha() <= 0f) {
1✔
819
            props.setAlpha(1f);
×
820
        }
821

822
        return props;
1✔
823
    }
824

825
    private void serializeTextProperties(final DataOutput out, final TextPropertiesImpl textProperties) throws IOException {
826
        serialize(out, textProperties.size);
1✔
827
        serialize(out, textProperties.rgba);
1✔
828
        serialize(out, textProperties.visible);
1✔
829
        serialize(out, textProperties.text);
1✔
830
        serialize(out, textProperties.width);
1✔
831
        serialize(out, textProperties.height);
1✔
832
    }
1✔
833

834
    private TextPropertiesImpl deserializeTextProperties(final DataInput is) throws IOException, ClassNotFoundException {
835
        float size = (Float) deserialize(is);
1✔
836
        int rgba = (Integer) deserialize(is);
1✔
837
        boolean visible = (Boolean) deserialize(is);
1✔
838
        String text = (String) deserialize(is);
1✔
839
        float width = (Float) deserialize(is);
1✔
840
        float height = (Float) deserialize(is);
1✔
841

842
        TextPropertiesImpl props = new TextPropertiesImpl();
1✔
843
        props.size = size;
1✔
844
        props.rgba = rgba;
1✔
845
        props.visible = visible;
1✔
846
        props.text = text;
1✔
847
        props.width = width;
1✔
848
        props.height = height;
1✔
849

850
        // Gephi versions before 0.11 used zero alpha to indicate that the element has
851
        // no color
852
        // Override this to avoid hidden elements
853
        if (props.getAlpha() <= 0f) {
1✔
854
            props.setAlpha(1f);
×
855
        }
856

857
        return props;
1✔
858
    }
859

860
    private void serializeTimestampSet(final DataOutput out, final TimestampSet timestampSet) throws IOException {
861
        serialize(out, timestampSet.toPrimitiveArray());
1✔
862
    }
1✔
863

864
    private TimestampSet deserializeTimestampSet(DataInput is) throws IOException, ClassNotFoundException {
865
        double[] r = (double[]) deserialize(is);
1✔
866

867
        return new TimestampSet(r);
1✔
868
    }
869

870
    private void serializeIntervalSet(final DataOutput out, final IntervalSet intervalSet) throws IOException {
871
        serialize(out, intervalSet.getIntervals());
1✔
872
    }
1✔
873

874
    private IntervalSet deserializeIntervalSet(DataInput is) throws IOException, ClassNotFoundException {
875
        double[] r = (double[]) deserialize(is);
1✔
876

877
        return new IntervalSet(r);
1✔
878
    }
879

880
    private void serializeTimestampMap(final DataOutput out, final TimestampMap timestampMap) throws IOException {
881
        serialize(out, timestampMap.getTimestamps());
1✔
882
        Class mapClass = timestampMap.getClass();
1✔
883
        if (mapClass.equals(TimestampBooleanMap.class)) {
1✔
884
            serialize(out, ((TimestampBooleanMap) timestampMap).toBooleanArray());
1✔
885
        } else if (mapClass.equals(TimestampByteMap.class)) {
1✔
886
            serialize(out, ((TimestampByteMap) timestampMap).toByteArray());
1✔
887
        } else if (mapClass.equals(TimestampCharMap.class)) {
1✔
888
            serialize(out, ((TimestampCharMap) timestampMap).toCharacterArray());
1✔
889
        } else if (mapClass.equals(TimestampDoubleMap.class)) {
1✔
890
            serialize(out, ((TimestampDoubleMap) timestampMap).toDoubleArray());
1✔
891
        } else if (mapClass.equals(TimestampFloatMap.class)) {
1✔
892
            serialize(out, ((TimestampFloatMap) timestampMap).toFloatArray());
1✔
893
        } else if (mapClass.equals(TimestampIntegerMap.class)) {
1✔
894
            serialize(out, ((TimestampIntegerMap) timestampMap).toIntegerArray());
1✔
895
        } else if (mapClass.equals(TimestampLongMap.class)) {
1✔
896
            serialize(out, ((TimestampLongMap) timestampMap).toLongArray());
1✔
897
        } else if (mapClass.equals(TimestampShortMap.class)) {
1✔
898
            serialize(out, ((TimestampShortMap) timestampMap).toShortArray());
1✔
899
        } else if (mapClass.equals(TimestampStringMap.class)) {
1✔
900
            serialize(out, timestampMap.toValuesArray());
1✔
901
        } else {
902
            throw new RuntimeException("Unrecognized timestamp map class");
×
903
        }
904
    }
1✔
905

906
    private TimestampMap deserializeTimestampMap(final DataInput is) throws IOException, ClassNotFoundException {
907
        double[] timeStamps = (double[]) deserialize(is);
1✔
908
        Object values = deserialize(is);
1✔
909

910
        Class mapClass = values.getClass();
1✔
911
        TimestampMap valueSet;
912
        if (mapClass.equals(boolean[].class)) {
1✔
913
            valueSet = new TimestampBooleanMap(timeStamps, (boolean[]) values);
1✔
914
        } else if (mapClass.equals(byte[].class)) {
1✔
915
            valueSet = new TimestampByteMap(timeStamps, (byte[]) values);
1✔
916
        } else if (mapClass.equals(char[].class)) {
1✔
917
            valueSet = new TimestampCharMap(timeStamps, (char[]) values);
1✔
918
        } else if (mapClass.equals(double[].class)) {
1✔
919
            valueSet = new TimestampDoubleMap(timeStamps, (double[]) values);
1✔
920
        } else if (mapClass.equals(float[].class)) {
1✔
921
            valueSet = new TimestampFloatMap(timeStamps, (float[]) values);
1✔
922
        } else if (mapClass.equals(int[].class)) {
1✔
923
            valueSet = new TimestampIntegerMap(timeStamps, (int[]) values);
1✔
924
        } else if (mapClass.equals(long[].class)) {
1✔
925
            valueSet = new TimestampLongMap(timeStamps, (long[]) values);
1✔
926
        } else if (mapClass.equals(short[].class)) {
1✔
927
            valueSet = new TimestampShortMap(timeStamps, (short[]) values);
1✔
928
        } else if (mapClass.equals(String[].class)) {
1✔
929
            valueSet = new TimestampStringMap(timeStamps, (String[]) values);
1✔
930
        } else {
931
            throw new RuntimeException("Unrecognized timestamp map class");
×
932
        }
933
        return valueSet;
1✔
934
    }
935

936
    private void serializeIntervalMap(final DataOutput out, final IntervalMap intervalMap) throws IOException {
937
        serialize(out, intervalMap.getIntervals());
1✔
938
        Class mapClass = intervalMap.getClass();
1✔
939
        if (mapClass.equals(IntervalBooleanMap.class)) {
1✔
940
            serialize(out, ((IntervalBooleanMap) intervalMap).toBooleanArray());
1✔
941
        } else if (mapClass.equals(IntervalByteMap.class)) {
1✔
942
            serialize(out, ((IntervalByteMap) intervalMap).toByteArray());
1✔
943
        } else if (mapClass.equals(IntervalCharMap.class)) {
1✔
944
            serialize(out, ((IntervalCharMap) intervalMap).toCharacterArray());
1✔
945
        } else if (mapClass.equals(IntervalDoubleMap.class)) {
1✔
946
            serialize(out, ((IntervalDoubleMap) intervalMap).toDoubleArray());
1✔
947
        } else if (mapClass.equals(IntervalFloatMap.class)) {
1✔
948
            serialize(out, ((IntervalFloatMap) intervalMap).toFloatArray());
1✔
949
        } else if (mapClass.equals(IntervalIntegerMap.class)) {
1✔
950
            serialize(out, ((IntervalIntegerMap) intervalMap).toIntegerArray());
1✔
951
        } else if (mapClass.equals(IntervalLongMap.class)) {
1✔
952
            serialize(out, ((IntervalLongMap) intervalMap).toLongArray());
1✔
953
        } else if (mapClass.equals(IntervalShortMap.class)) {
1✔
954
            serialize(out, ((IntervalShortMap) intervalMap).toShortArray());
1✔
955
        } else if (mapClass.equals(IntervalStringMap.class)) {
1✔
956
            serialize(out, intervalMap.toValuesArray());
1✔
957
        } else {
958
            throw new RuntimeException("Unrecognized interval map class");
×
959
        }
960
    }
1✔
961

962
    private IntervalMap deserializeIntervalMap(final DataInput is) throws IOException, ClassNotFoundException {
963
        double[] intervals = (double[]) deserialize(is);
1✔
964
        Object values = deserialize(is);
1✔
965

966
        Class mapClass = values.getClass();
1✔
967
        IntervalMap valueSet;
968
        if (mapClass.equals(boolean[].class)) {
1✔
969
            valueSet = new IntervalBooleanMap(intervals, (boolean[]) values);
1✔
970
        } else if (mapClass.equals(byte[].class)) {
1✔
971
            valueSet = new IntervalByteMap(intervals, (byte[]) values);
1✔
972
        } else if (mapClass.equals(char[].class)) {
1✔
973
            valueSet = new IntervalCharMap(intervals, (char[]) values);
1✔
974
        } else if (mapClass.equals(double[].class)) {
1✔
975
            valueSet = new IntervalDoubleMap(intervals, (double[]) values);
1✔
976
        } else if (mapClass.equals(float[].class)) {
1✔
977
            valueSet = new IntervalFloatMap(intervals, (float[]) values);
1✔
978
        } else if (mapClass.equals(int[].class)) {
1✔
979
            valueSet = new IntervalIntegerMap(intervals, (int[]) values);
1✔
980
        } else if (mapClass.equals(long[].class)) {
1✔
981
            valueSet = new IntervalLongMap(intervals, (long[]) values);
1✔
982
        } else if (mapClass.equals(short[].class)) {
1✔
983
            valueSet = new IntervalShortMap(intervals, (short[]) values);
1✔
984
        } else if (mapClass.equals(String[].class)) {
1✔
985
            valueSet = new IntervalStringMap(intervals, (String[]) values);
1✔
986
        } else {
987
            throw new RuntimeException("Unrecognized interval map class");
×
988
        }
989
        return valueSet;
1✔
990
    }
991

992
    private void serializeTimestampIndexStore(final DataOutput out, final TimestampIndexStore timestampIndexStore) throws IOException {
993
        serialize(out, timestampIndexStore.elementType);
1✔
994

995
        serialize(out, timestampIndexStore.length);
1✔
996
        serialize(out, timestampIndexStore.getMap().keySet().toDoubleArray());
1✔
997
        serialize(out, timestampIndexStore.getMap().values().toIntArray());
1✔
998
        serialize(out, timestampIndexStore.garbageQueue.toIntArray());
1✔
999
        serialize(out, timestampIndexStore.countMap);
1✔
1000
    }
1✔
1001

1002
    private TimestampIndexStore deserializeTimestampIndexStore(final DataInput is) throws IOException, ClassNotFoundException {
1003
        TimestampIndexStore timestampIndexStore;
1004

1005
        Class cls = (Class) deserialize(is);
1✔
1006
        if (cls.equals(Node.class)) {
1✔
1007
            timestampIndexStore = (TimestampIndexStore) model.store.timeStore.nodeIndexStore;
1✔
1008
        } else {
1009
            timestampIndexStore = (TimestampIndexStore) model.store.timeStore.edgeIndexStore;
1✔
1010
        }
1011

1012
        int length = (Integer) deserialize(is);
1✔
1013
        double[] doubles = (double[]) deserialize(is);
1✔
1014
        int[] ints = (int[]) deserialize(is);
1✔
1015
        int[] garbage = (int[]) deserialize(is);
1✔
1016
        int[] counts = (int[]) deserialize(is);
1✔
1017

1018
        timestampIndexStore.length = length;
1✔
1019
        for (int i : garbage) {
1✔
1020
            timestampIndexStore.garbageQueue.add(i);
1✔
1021
        }
1022
        Double2IntMap m = timestampIndexStore.getMap();
1✔
1023
        for (int i = 0; i < ints.length; i++) {
1✔
1024
            m.put(doubles[i], ints[i]);
1✔
1025
        }
1026
        timestampIndexStore.countMap = counts;
1✔
1027
        return timestampIndexStore;
1✔
1028
    }
1029

1030
    private void serializeIntervalIndexStore(final DataOutput out, final IntervalIndexStore intervalIndexStore) throws IOException {
1031
        serialize(out, intervalIndexStore.elementType);
1✔
1032

1033
        serialize(out, intervalIndexStore.length);
1✔
1034
        serialize(out, intervalIndexStore.getMap().size());
1✔
1035
        for (Map.Entry<Interval, Integer> entry : intervalIndexStore.getMap().entrySet()) {
1✔
1036
            serialize(out, entry.getKey());
1✔
1037
            serialize(out, entry.getValue());
1✔
1038
        }
1✔
1039
        serialize(out, intervalIndexStore.garbageQueue.toIntArray());
1✔
1040
        serialize(out, intervalIndexStore.countMap);
1✔
1041
    }
1✔
1042

1043
    private IntervalIndexStore deserializeIntervalIndexStore(final DataInput is) throws IOException, ClassNotFoundException {
1044
        IntervalIndexStore intervalIndexStore;
1045

1046
        Class cls = (Class) deserialize(is);
1✔
1047
        if (cls.equals(Node.class)) {
1✔
1048
            intervalIndexStore = (IntervalIndexStore) model.store.timeStore.nodeIndexStore;
1✔
1049
        } else {
1050
            intervalIndexStore = (IntervalIndexStore) model.store.timeStore.edgeIndexStore;
1✔
1051
        }
1052

1053
        int length = (Integer) deserialize(is);
1✔
1054
        int mapSize = (Integer) deserialize(is);
1✔
1055

1056
        Interval2IntTreeMap map = intervalIndexStore.getMap();
1✔
1057
        for (int i = 0; i < mapSize; i++) {
1✔
1058
            Interval key = (Interval) deserialize(is);
1✔
1059
            Integer value = (Integer) deserialize(is);
1✔
1060
            map.put(key, value);
1✔
1061
        }
1062
        int[] garbage = (int[]) deserialize(is);
1✔
1063
        int[] counts = (int[]) deserialize(is);
1✔
1064

1065
        intervalIndexStore.length = length;
1✔
1066
        for (int i : garbage) {
1✔
1067
            intervalIndexStore.garbageQueue.add(i);
1✔
1068
        }
1069
        intervalIndexStore.countMap = counts;
1✔
1070
        return intervalIndexStore;
1✔
1071
    }
1072

1073
    private void serializeInstant(final DataOutput out, final Instant instant) throws IOException {
1074
        serialize(out, instant.getEpochSecond());
1✔
1075
        serialize(out, instant.getNano());
1✔
1076
    }
1✔
1077

1078
    private Instant deserializeInstant(final DataInput is) throws IOException, ClassNotFoundException {
1079
        long epochSecond = (long) deserialize(is);
1✔
1080
        int nano = (int) deserialize(is);
1✔
1081
        return Instant.ofEpochSecond(epochSecond, nano);
1✔
1082
    }
1083

1084
    private void serializeGraphAttributes(final DataOutput out, final GraphAttributesImpl graphAttributes) throws IOException {
1085
        serialize(out, graphAttributes.attributes.size());
1✔
1086
        for (Map.Entry<String, Object> entry : graphAttributes.attributes.entrySet()) {
1✔
1087
            serialize(out, entry.getKey());
1✔
1088
            serialize(out, entry.getValue());
1✔
1089
        }
1✔
1090
    }
1✔
1091

1092
    private GraphAttributesImpl deserializeGraphAttributes(final DataInput is) throws IOException, ClassNotFoundException {
1093
        GraphAttributesImpl attributes = new GraphAttributesImpl();
1✔
1094
        int size = (Integer) deserialize(is);
1✔
1095
        for (int i = 0; i < size; i++) {
1✔
1096
            String key = (String) deserialize(is);
1✔
1097
            Object value = deserialize(is);
1✔
1098
            attributes.attributes.put(key, value);
1✔
1099
        }
1100
        return attributes;
1✔
1101
    }
1102

1103
    private void serializeTimeFormat(final DataOutput out, final TimeFormat timeFormat) throws IOException {
1104
        serialize(out, timeFormat.name());
1✔
1105
    }
1✔
1106

1107
    private TimeFormat deserializeTimeFormat(final DataInput is) throws IOException, ClassNotFoundException {
1108
        String name = (String) deserialize(is);
1✔
1109

1110
        TimeFormat tf = TimeFormat.valueOf(name);
1✔
1111
        model.store.timeFormat = tf;
1✔
1112

1113
        return tf;
1✔
1114
    }
1115

1116
    private void serializeTimeZone(final DataOutput out, final ZoneId timeZone) throws IOException {
1117
        serialize(out, timeZone.getId());
1✔
1118
    }
1✔
1119

1120
    private ZoneId deserializeTimeZone(final DataInput is) throws IOException, ClassNotFoundException {
1121
        String id = (String) deserialize(is);
1✔
1122

1123
        ZoneId tz = ZoneId.of(id);
1✔
1124
        model.store.timeZone = tz;
1✔
1125

1126
        return tz;
1✔
1127
    }
1128

1129
    private void serializeTimeStore(final DataOutput out) throws IOException {
1130
        TimeStore timeStore = model.store.timeStore;
1✔
1131

1132
        serialize(out, timeStore.nodeIndexStore);
1✔
1133
        serialize(out, timeStore.edgeIndexStore);
1✔
1134
    }
1✔
1135

1136
    private void serializeInterval(final DataOutput out, final Interval interval) throws IOException {
1137
        serialize(out, interval.getLow());
1✔
1138
        serialize(out, interval.getHigh());
1✔
1139
    }
1✔
1140

1141
    private Interval deserializeInterval(final DataInput is) throws IOException, ClassNotFoundException {
1142
        double start = (Double) deserialize(is);
1✔
1143
        double end = (Double) deserialize(is);
1✔
1144
        return new Interval(start, end);
1✔
1145
    }
1146

1147
    private TimeStore deserializeTimeStore(final DataInput is) throws IOException, ClassNotFoundException {
1148
        TimeStore timeStore = model.store.timeStore;
1✔
1149

1150
        deserialize(is);
1✔
1151
        deserialize(is);
1✔
1152

1153
        return timeStore;
1✔
1154
    }
1155

1156
    private void serializeConfiguration(final DataOutput out) throws IOException {
1157
        ConfigurationImpl config = model.configuration;
1✔
1158

1159
        serialize(out, config.getNodeIdType());
1✔
1160
        serialize(out, config.getEdgeIdType());
1✔
1161
        serialize(out, config.getEdgeLabelType());
1✔
1162
        serialize(out, config.getEdgeWeightType());
1✔
1163
        serialize(out, config.getTimeRepresentation());
1✔
1164
        serialize(out, config.isEdgeWeightColumn());
1✔
1165
    }
1✔
1166

1167
    private ConfigurationImpl deserializeConfiguration(final DataInput is) throws IOException, ClassNotFoundException {
1168
        Configuration.Builder config = Configuration.builder();
1✔
1169

1170
        Class nodeIdType = (Class) deserialize(is);
1✔
1171
        Class edgeIdType = (Class) deserialize(is);
1✔
1172
        Class edgeLabelType = (Class) deserialize(is);
1✔
1173
        Class edgeWeightType = (Class) deserialize(is);
1✔
1174
        TimeRepresentation timeRepresentation = (TimeRepresentation) deserialize(is);
1✔
1175

1176
        config.nodeIdType(nodeIdType);
1✔
1177
        config.edgeIdType(edgeIdType);
1✔
1178
        config.edgeLabelType(edgeLabelType);
1✔
1179
        config.edgeWeightType(edgeWeightType);
1✔
1180
        config.timeRepresentation(timeRepresentation);
1✔
1181
        if (readVersion >= 0.5) {
1✔
1182
            Boolean edgeColumn = (Boolean) deserialize(is);
1✔
1183
            config.edgeWeightColumn(edgeColumn);
1✔
1184
        }
1185

1186
        return new ConfigurationImpl(config.build());
1✔
1187
    }
1188

1189
    private void serializeList(final DataOutput out, final List list) throws IOException {
1190
        Class oCls = list.getClass();
1✔
1191
        if (oCls.equals(IntArrayList.class)) {
1✔
1192
            serialize(out, ((IntArrayList) list).toIntArray());
1✔
1193
        } else if (oCls.equals(FloatArrayList.class)) {
1✔
1194
            serialize(out, ((FloatArrayList) list).toFloatArray());
1✔
1195
        } else if (oCls.equals(DoubleArrayList.class)) {
1✔
1196
            serialize(out, ((DoubleArrayList) list).toDoubleArray());
1✔
1197
        } else if (oCls.equals(ShortArrayList.class)) {
1✔
1198
            serialize(out, ((ShortArrayList) list).toShortArray());
1✔
1199
        } else if (oCls.equals(ByteArrayList.class)) {
1✔
1200
            serialize(out, ((ByteArrayList) list).toByteArray());
1✔
1201
        } else if (oCls.equals(LongArrayList.class)) {
1✔
1202
            serialize(out, ((LongArrayList) list).toLongArray());
1✔
1203
        } else if (oCls.equals(BooleanArrayList.class)) {
1✔
1204
            serialize(out, ((BooleanArrayList) list).toBooleanArray());
1✔
1205
        } else if (oCls.equals(CharArrayList.class)) {
1✔
1206
            serialize(out, ((CharArrayList) list).toCharArray());
1✔
1207
        } else {
1208
            serialize(out, list.size());
1✔
1209
            for (Object obj : list) {
1✔
1210
                serialize(out, obj);
1✔
1211
            }
1✔
1212
        }
1213
    }
1✔
1214

1215
    private List deserializeList(final DataInput is) throws IOException, ClassNotFoundException {
1216
        Object h = deserialize(is);
1✔
1217
        Class oCls = h.getClass();
1✔
1218
        if (oCls.equals(Integer.class)) {
1✔
1219
            int size = (Integer) h;
1✔
1220
            ObjectArrayList list = new ObjectArrayList(size);
1✔
1221
            for (int i = 0; i < size; i++) {
1✔
1222
                list.add(deserialize(is));
1✔
1223
            }
1224
            return list;
1✔
1225
        } else if (oCls.equals(int[].class)) {
1✔
1226
            return new IntArrayList((int[]) h);
1✔
1227
        } else if (oCls.equals(float[].class)) {
1✔
1228
            return new FloatArrayList((float[]) h);
1✔
1229
        } else if (oCls.equals(double[].class)) {
1✔
1230
            return new DoubleArrayList((double[]) h);
1✔
1231
        } else if (oCls.equals(short[].class)) {
1✔
1232
            return new ShortArrayList((short[]) h);
1✔
1233
        } else if (oCls.equals(byte[].class)) {
1✔
1234
            return new ByteArrayList((byte[]) h);
1✔
1235
        } else if (oCls.equals(long[].class)) {
1✔
1236
            return new LongArrayList((long[]) h);
1✔
1237
        } else if (oCls.equals(boolean[].class)) {
1✔
1238
            return new BooleanArrayList((boolean[]) h);
1✔
1239
        } else if (oCls.equals(char[].class)) {
1✔
1240
            return new CharArrayList((char[]) h);
1✔
1241
        }
1242
        throw new EOFException();
×
1243
    }
1244

1245
    private void serializeSet(final DataOutput out, final Set set) throws IOException {
1246
        Class oCls = set.getClass();
1✔
1247
        if (oCls.equals(IntOpenHashSet.class)) {
1✔
1248
            serialize(out, ((IntOpenHashSet) set).toIntArray());
1✔
1249
        } else if (oCls.equals(FloatOpenHashSet.class)) {
1✔
1250
            serialize(out, ((FloatOpenHashSet) set).toFloatArray());
1✔
1251
        } else if (oCls.equals(DoubleOpenHashSet.class)) {
1✔
1252
            serialize(out, ((DoubleOpenHashSet) set).toDoubleArray());
1✔
1253
        } else if (oCls.equals(ShortOpenHashSet.class)) {
1✔
1254
            serialize(out, ((ShortOpenHashSet) set).toShortArray());
1✔
1255
        } else if (oCls.equals(ByteOpenHashSet.class)) {
1✔
1256
            serialize(out, ((ByteOpenHashSet) set).toByteArray());
1✔
1257
        } else if (oCls.equals(LongOpenHashSet.class)) {
1✔
1258
            serialize(out, ((LongOpenHashSet) set).toLongArray());
1✔
1259
        } else if (oCls.equals(BooleanOpenHashSet.class)) {
1✔
1260
            serialize(out, ((BooleanOpenHashSet) set).toBooleanArray());
1✔
1261
        } else if (oCls.equals(CharOpenHashSet.class)) {
1✔
1262
            serialize(out, ((CharOpenHashSet) set).toCharArray());
1✔
1263
        } else {
1264
            serialize(out, set.size());
1✔
1265
            for (Object obj : set) {
1✔
1266
                serialize(out, obj);
1✔
1267
            }
1✔
1268
        }
1269
    }
1✔
1270

1271
    private Set deserializeSet(final DataInput is) throws IOException, ClassNotFoundException {
1272
        Object h = deserialize(is);
1✔
1273
        Class oCls = h.getClass();
1✔
1274
        if (oCls.equals(Integer.class)) {
1✔
1275
            int size = (Integer) h;
1✔
1276
            ObjectOpenHashSet set = new ObjectOpenHashSet(size);
1✔
1277
            for (int i = 0; i < size; i++) {
1✔
1278
                set.add(deserialize(is));
1✔
1279
            }
1280
            return set;
1✔
1281
        } else if (oCls.equals(int[].class)) {
1✔
1282
            return new IntOpenHashSet((int[]) h);
1✔
1283
        } else if (oCls.equals(float[].class)) {
1✔
1284
            return new FloatOpenHashSet((float[]) h);
1✔
1285
        } else if (oCls.equals(double[].class)) {
1✔
1286
            return new DoubleOpenHashSet((double[]) h);
1✔
1287
        } else if (oCls.equals(short[].class)) {
1✔
1288
            return new ShortOpenHashSet((short[]) h);
1✔
1289
        } else if (oCls.equals(byte[].class)) {
1✔
1290
            return new ByteOpenHashSet((byte[]) h);
1✔
1291
        } else if (oCls.equals(long[].class)) {
1✔
1292
            return new LongOpenHashSet((long[]) h);
1✔
1293
        } else if (oCls.equals(boolean[].class)) {
1✔
1294
            return new BooleanOpenHashSet((boolean[]) h);
1✔
1295
        } else if (oCls.equals(char[].class)) {
1✔
1296
            return new CharOpenHashSet((char[]) h);
1✔
1297
        }
1298
        throw new EOFException();
×
1299
    }
1300

1301
    private void serializeMap(final DataOutput out, final Map map) throws IOException {
1302
        Class oCls = map.getClass();
1✔
1303
        if (oCls.equals(Int2ObjectOpenHashMap.class)) {
1✔
1304
            serialize(out, ((Int2ObjectOpenHashMap) map).keySet().toIntArray());
1✔
1305
            serialize(out, map.values().toArray());
1✔
1306
        } else if (oCls.equals(Float2ObjectOpenHashMap.class)) {
1✔
1307
            serialize(out, ((Float2ObjectOpenHashMap) map).keySet().toFloatArray());
1✔
1308
            serialize(out, map.values().toArray());
1✔
1309
        } else if (oCls.equals(Double2ObjectOpenHashMap.class)) {
1✔
1310
            serialize(out, ((Double2ObjectOpenHashMap) map).keySet().toDoubleArray());
1✔
1311
            serialize(out, map.values().toArray());
1✔
1312
        } else if (oCls.equals(Short2ObjectOpenHashMap.class)) {
1✔
1313
            serialize(out, ((Short2ObjectOpenHashMap) map).keySet().toShortArray());
1✔
1314
            serialize(out, map.values().toArray());
1✔
1315
        } else if (oCls.equals(Long2ObjectOpenHashMap.class)) {
1✔
1316
            serialize(out, ((Long2ObjectOpenHashMap) map).keySet().toLongArray());
1✔
1317
            serialize(out, map.values().toArray());
1✔
1318
        } else if (oCls.equals(Byte2ObjectOpenHashMap.class)) {
1✔
1319
            serialize(out, ((Byte2ObjectOpenHashMap) map).keySet().toByteArray());
1✔
1320
            serialize(out, map.values().toArray());
1✔
1321
        } else if (oCls.equals(Char2ObjectOpenHashMap.class)) {
1✔
1322
            serialize(out, ((Char2ObjectOpenHashMap) map).keySet().toCharArray());
1✔
1323
            serialize(out, map.values().toArray());
1✔
1324
        } else {
1325
            serialize(out, map.size());
1✔
1326

1327
            Set<Map.Entry<Object, Object>> entrySet = map.entrySet();
1✔
1328
            for (Map.Entry entry : entrySet) {
1✔
1329
                serialize(out, entry.getKey());
1✔
1330
                serialize(out, entry.getValue());
1✔
1331
            }
1✔
1332
        }
1333
    }
1✔
1334

1335
    private Map deserializeMap(final DataInput is) throws IOException, ClassNotFoundException {
1336
        Object h = deserialize(is);
1✔
1337
        Class oCls = h.getClass();
1✔
1338
        if (oCls.equals(Integer.class)) {
1✔
1339
            int size = (Integer) h;
1✔
1340
            Object2ObjectOpenHashMap set = new Object2ObjectOpenHashMap(size);
1✔
1341
            for (int i = 0; i < size; i++) {
1✔
1342
                set.put(deserialize(is), deserialize(is));
1✔
1343
            }
1344
            return set;
1✔
1345
        } else if (oCls.equals(int[].class)) {
1✔
1346
            return new Int2ObjectOpenHashMap((int[]) h, (Object[]) deserialize(is));
1✔
1347
        } else if (oCls.equals(float[].class)) {
1✔
1348
            return new Float2ObjectOpenHashMap((float[]) h, (Object[]) deserialize(is));
1✔
1349
        } else if (oCls.equals(double[].class)) {
1✔
1350
            return new Double2ObjectOpenHashMap((double[]) h, (Object[]) deserialize(is));
1✔
1351
        } else if (oCls.equals(short[].class)) {
1✔
1352
            return new Short2ObjectOpenHashMap((short[]) h, (Object[]) deserialize(is));
1✔
1353
        } else if (oCls.equals(byte[].class)) {
1✔
1354
            return new Byte2ObjectOpenHashMap((byte[]) h, (Object[]) deserialize(is));
1✔
1355
        } else if (oCls.equals(long[].class)) {
1✔
1356
            return new Long2ObjectOpenHashMap((long[]) h, (Object[]) deserialize(is));
1✔
1357
        } else if (oCls.equals(char[].class)) {
1✔
1358
            return new Char2ObjectOpenHashMap((char[]) h, (Object[]) deserialize(is));
1✔
1359
        }
1360
        throw new EOFException();
×
1361
    }
1362

1363
    // SERIALIZE PRIMITIVES
1364
    protected byte[] serialize(Object obj) throws IOException {
1365
        DataInputOutput ba = new DataInputOutput();
1✔
1366

1367
        serialize(ba, obj);
1✔
1368

1369
        return ba.toByteArray();
1✔
1370
    }
1371

1372
    protected void serialize(final DataOutput out, final Object obj) throws IOException {
1373
        final Class clazz = obj != null ? obj.getClass() : null;
1✔
1374

1375
        if (obj == null) {
1✔
1376
            out.write(NULL);
1✔
1377

1378
        } else if (clazz == Boolean.class) {
1✔
1379
            if (((Boolean) obj)) {
1✔
1380
                out.write(BOOLEAN_TRUE);
1✔
1381
            } else {
1382
                out.write(BOOLEAN_FALSE);
1✔
1383

1384
            }
1385
        } else if (clazz == Integer.class) {
1✔
1386
            final int val = (Integer) obj;
1✔
1387
            writeInteger(out, val);
1✔
1388

1389
        } else if (clazz == Double.class) {
1✔
1390
            double v = (Double) obj;
1✔
1391
            if (v == -1d) {
1✔
1392
                out.write(DOUBLE_MINUS_1);
1✔
1393
            } else if (v == 0d) {
1✔
1394
                out.write(DOUBLE_0);
1✔
1395
            } else if (v == 1d) {
1✔
1396
                out.write(DOUBLE_1);
1✔
1397
            } else if (v >= 0 && v <= 255 && (int) v == v) {
1✔
1398
                out.write(DOUBLE_255);
1✔
1399
                out.write((int) v);
1✔
1400
            } else if (v >= Short.MIN_VALUE && v <= Short.MAX_VALUE && (short) v == v) {
1✔
1401
                out.write(DOUBLE_SHORT);
1✔
1402
                out.writeShort((int) v);
1✔
1403
            } else {
1404
                out.write(DOUBLE_FULL);
1✔
1405
                out.writeDouble(v);
1✔
1406

1407
            }
1408
        } else if (clazz == Float.class) {
1✔
1409
            float v = (Float) obj;
1✔
1410
            if (v == -1f) {
1✔
1411
                out.write(FLOAT_MINUS_1);
1✔
1412
            } else if (v == 0f) {
1✔
1413
                out.write(FLOAT_0);
1✔
1414
            } else if (v == 1f) {
1✔
1415
                out.write(FLOAT_1);
1✔
1416
            } else if (v >= 0 && v <= 255 && (int) v == v) {
1✔
1417
                out.write(FLOAT_255);
1✔
1418
                out.write((int) v);
1✔
1419
            } else if (v >= Short.MIN_VALUE && v <= Short.MAX_VALUE && (short) v == v) {
1✔
1420
                out.write(FLOAT_SHORT);
1✔
1421
                out.writeShort((int) v);
1✔
1422

1423
            } else {
1424
                out.write(FLOAT_FULL);
1✔
1425
                out.writeFloat(v);
1✔
1426

1427
            }
1428
        } else if (clazz == Long.class) {
1✔
1429
            final long val = (Long) obj;
1✔
1430
            writeLong(out, val);
1✔
1431

1432
        } else if (clazz == BigInteger.class) {
1✔
1433
            out.write(BIGINTEGER);
1✔
1434
            byte[] buf = ((BigInteger) obj).toByteArray();
1✔
1435
            serializeByteArrayInt(out, buf);
1✔
1436

1437
        } else if (clazz == BigDecimal.class) {
1✔
1438
            out.write(BIGDECIMAL);
1✔
1439
            BigDecimal d = (BigDecimal) obj;
1✔
1440
            serializeByteArrayInt(out, d.unscaledValue().toByteArray());
1✔
1441
            LongPacker.packInt(out, d.scale());
1✔
1442

1443
        } else if (clazz == Short.class) {
1✔
1444
            short val = (Short) obj;
1✔
1445
            if (val == -1) {
1✔
1446
                out.write(SHORT_MINUS_1);
1✔
1447
            } else if (val == 0) {
1✔
1448
                out.write(SHORT_0);
1✔
1449
            } else if (val == 1) {
1✔
1450
                out.write(SHORT_1);
1✔
1451
            } else if (val > 0 && val < 255) {
1✔
1452
                out.write(SHORT_255);
1✔
1453
                out.write(val);
1✔
1454
            } else {
1455
                out.write(SHORT_FULL);
1✔
1456
                out.writeShort(val);
1✔
1457

1458
            }
1459
        } else if (clazz == Byte.class) {
1✔
1460
            byte val = (Byte) obj;
1✔
1461
            if (val == -1) {
1✔
1462
                out.write(BYTE_MINUS_1);
1✔
1463
            } else if (val == 0) {
1✔
1464
                out.write(BYTE_0);
1✔
1465
            } else if (val == 1) {
1✔
1466
                out.write(BYTE_1);
1✔
1467
            } else {
1468
                out.write(BYTE_FULL);
1✔
1469
                out.writeByte(val);
1✔
1470

1471
            }
1472
        } else if (clazz == Character.class) {
1✔
1473
            out.write(CHAR);
1✔
1474
            // Write as 2-byte short so the encoding doesn't depend on the DataOutput
1475
            // implementation. Byte-identical to DataOutputStream.writeChar().
1476
            out.writeShort((Character) obj);
1✔
1477

1478
        } else if (clazz == String.class) {
1✔
1479
            String s = (String) obj;
1✔
1480
            if (s.length() == 0) {
1✔
1481
                out.write(STRING_EMPTY);
1✔
1482
            } else {
1483
                out.write(STRING);
1✔
1484
                serializeString(out, s);
1✔
1485
            }
1486
        } else if (obj instanceof Class) {
1✔
1487
            out.write(CLASS);
1✔
1488
            serialize(out, ((Class) obj).getName());
1✔
1489
        } else if (obj instanceof int[]) {
1✔
1490
            writeIntArray(out, (int[]) obj);
1✔
1491
        } else if (obj instanceof long[]) {
1✔
1492
            writeLongArray(out, (long[]) obj);
1✔
1493
        } else if (obj instanceof short[]) {
1✔
1494
            out.write(SHORT_ARRAY);
1✔
1495
            short[] a = (short[]) obj;
1✔
1496
            LongPacker.packInt(out, a.length);
1✔
1497
            for (short s : a) {
1✔
1498
                out.writeShort(s);
1✔
1499
            }
1500
        } else if (obj instanceof boolean[]) {
1✔
1501
            out.write(BOOLEAN_ARRAY);
1✔
1502
            boolean[] a = (boolean[]) obj;
1✔
1503
            LongPacker.packInt(out, a.length);
1✔
1504
            for (boolean s : a) {
1✔
1505
                out.writeBoolean(s); // TODO pack 8 booleans to single byte
1✔
1506
            }
1507
        } else if (obj instanceof double[]) {
1✔
1508
            out.write(DOUBLE_ARRAY);
1✔
1509
            double[] a = (double[]) obj;
1✔
1510
            LongPacker.packInt(out, a.length);
1✔
1511
            for (double s : a) {
1✔
1512
                out.writeDouble(s);
1✔
1513
            }
1514
        } else if (obj instanceof float[]) {
1✔
1515
            out.write(FLOAT_ARRAY);
1✔
1516
            float[] a = (float[]) obj;
1✔
1517
            LongPacker.packInt(out, a.length);
1✔
1518
            for (float s : a) {
1✔
1519
                out.writeFloat(s);
1✔
1520
            }
1521
        } else if (obj instanceof char[]) {
1✔
1522
            out.write(CHAR_ARRAY);
1✔
1523
            char[] a = (char[]) obj;
1✔
1524
            LongPacker.packInt(out, a.length);
1✔
1525
            for (char s : a) {
1✔
1526
                // See CHAR above: 2-byte encoding, independent of the DataOutput impl.
1527
                out.writeShort(s);
1✔
1528
            }
1529
        } else if (obj instanceof byte[]) {
1✔
1530
            byte[] b = (byte[]) obj;
1✔
1531
            out.write(ARRAY_BYTE_INT);
1✔
1532
            serializeByteArrayInt(out, b);
1✔
1533

1534
        } else if (clazz == Date.class) {
1✔
1535
            out.write(DATE);
1✔
1536
            out.writeLong(((Date) obj).getTime());
1✔
1537

1538
        } else if (obj instanceof String[]) {
1✔
1539
            String[] b = (String[]) obj;
1✔
1540
            out.write(STRING_ARRAY);
1✔
1541
            LongPacker.packInt(out, b.length);
1✔
1542
            for (String s : b) {
1✔
1543
                serializeString(out, s);
1✔
1544
            }
1545
        } else if (obj instanceof Object[]) {
1✔
1546
            Object[] b = (Object[]) obj;
1✔
1547
            out.write(ARRAY_OBJECT);
1✔
1548
            LongPacker.packInt(out, b.length);
1✔
1549
            for (Object o : b) {
1✔
1550
                serialize(out, o);
1✔
1551
            }
1552
        } else if (obj instanceof TimestampSet) {
1✔
1553
            TimestampSet b = (TimestampSet) obj;
1✔
1554
            out.write(TIMESTAMP_SET);
1✔
1555
            serializeTimestampSet(out, b);
1✔
1556
        } else if (obj instanceof IntervalSet) {
1✔
1557
            IntervalSet b = (IntervalSet) obj;
1✔
1558
            out.write(INTERVAL_SET);
1✔
1559
            serializeIntervalSet(out, b);
1✔
1560
        } else if (obj instanceof NodeImpl) {
1✔
1561
            NodeImpl b = (NodeImpl) obj;
1✔
1562
            out.write(NODE);
1✔
1563
            serializeNode(out, b);
1✔
1564
        } else if (obj instanceof EdgeImpl) {
1✔
1565
            EdgeImpl b = (EdgeImpl) obj;
1✔
1566
            out.write(EDGE);
1✔
1567
            serializeEdge(out, b);
1✔
1568
        } else if (obj instanceof EdgeTypeStore) {
1✔
1569
            EdgeTypeStore b = (EdgeTypeStore) obj;
1✔
1570
            out.write(EDGETYPE_STORE);
1✔
1571
            serializeEdgeTypeStore(out);
1✔
1572
        } else if (obj instanceof Origin) {
1✔
1573
            Origin b = (Origin) obj;
1✔
1574
            out.write(COLUMN_ORIGIN);
1✔
1575
            serialize(out, b.name());
1✔
1576
        } else if (obj instanceof TableImpl) {
1✔
1577
            TableImpl b = (TableImpl) obj;
1✔
1578
            out.write(TABLE);
1✔
1579
            serializeTable(out, b);
1✔
1580
        } else if (obj instanceof GraphStore) {
1✔
1581
            GraphStore b = (GraphStore) obj;
1✔
1582
            out.write(GRAPH_STORE);
1✔
1583
            serializeGraphStore(out, b);
1✔
1584
        } else if (obj instanceof GraphFactoryImpl) {
1✔
1585
            GraphFactoryImpl b = (GraphFactoryImpl) obj;
1✔
1586
            out.write(GRAPH_FACTORY);
1✔
1587
            serializeGraphFactory(out);
1✔
1588
        } else if (obj instanceof GraphViewStore) {
1✔
1589
            GraphViewStore b = (GraphViewStore) obj;
1✔
1590
            out.write(GRAPH_VIEW_STORE);
1✔
1591
            serializeViewStore(out);
1✔
1592
        } else if (obj instanceof GraphViewImpl) {
1✔
1593
            GraphViewImpl b = (GraphViewImpl) obj;
1✔
1594
            out.write(GRAPH_VIEW);
1✔
1595
            serializeGraphView(out, b);
1✔
1596
        } else if (obj instanceof BitSet) {
1✔
1597
            BitSet bs = (BitSet) obj;
1✔
1598
            out.write(BIT_VECTOR);
1✔
1599
            serializeBitSet(out, bs);
1✔
1600
        } else if (obj instanceof GraphVersion) {
1✔
1601
            GraphVersion b = (GraphVersion) obj;
1✔
1602
            out.write(GRAPH_VERSION);
1✔
1603
            serializeGraphVersion(out, b);
1✔
1604
        } else if (obj instanceof NodePropertiesImpl) {
1✔
1605
            NodePropertiesImpl b = (NodePropertiesImpl) obj;
1✔
1606
            out.write(NODE_PROPERTIES);
1✔
1607
            serializeNodeProperties(out, b);
1✔
1608
        } else if (obj instanceof EdgePropertiesImpl) {
1✔
1609
            EdgePropertiesImpl b = (EdgePropertiesImpl) obj;
1✔
1610
            out.write(EDGE_PROPERTIES);
1✔
1611
            serializeEdgeProperties(out, b);
1✔
1612
        } else if (obj instanceof TextPropertiesImpl) {
1✔
1613
            TextPropertiesImpl b = (TextPropertiesImpl) obj;
1✔
1614
            out.write(TEXT_PROPERTIES);
1✔
1615
            serializeTextProperties(out, b);
1✔
1616
        } else if (obj instanceof Estimator) {
1✔
1617
            Estimator b = (Estimator) obj;
1✔
1618
            out.write(ESTIMATOR);
1✔
1619
            serializeString(out, b.name());
1✔
1620
        } else if (obj instanceof TimeRepresentation) {
1✔
1621
            TimeRepresentation b = (TimeRepresentation) obj;
1✔
1622
            out.write(TIME_REPRESENTATION);
1✔
1623
            serializeString(out, b.name());
1✔
1624
        } else if (obj instanceof TimestampMap) {
1✔
1625
            TimestampMap b = (TimestampMap) obj;
1✔
1626
            out.write(TIMESTAMP_MAP);
1✔
1627
            serializeTimestampMap(out, b);
1✔
1628
        } else if (obj instanceof IntervalMap) {
1✔
1629
            IntervalMap b = (IntervalMap) obj;
1✔
1630
            out.write(INTERVAL_MAP);
1✔
1631
            serializeIntervalMap(out, b);
1✔
1632
        } else if (obj instanceof TimestampIndexStore) {
1✔
1633
            TimestampIndexStore b = (TimestampIndexStore) obj;
1✔
1634
            out.write(TIMESTAMP_INDEX_STORE);
1✔
1635
            serializeTimestampIndexStore(out, b);
1✔
1636
        } else if (obj instanceof IntervalIndexStore) {
1✔
1637
            IntervalIndexStore b = (IntervalIndexStore) obj;
1✔
1638
            out.write(INTERVAL_INDEX_STORE);
1✔
1639
            serializeIntervalIndexStore(out, b);
1✔
1640
        } else if (obj instanceof GraphAttributesImpl) {
1✔
1641
            GraphAttributesImpl b = (GraphAttributesImpl) obj;
1✔
1642
            out.write(GRAPH_ATTRIBUTES);
1✔
1643
            serializeGraphAttributes(out, b);
1✔
1644
        } else if (obj instanceof TimeFormat) {
1✔
1645
            TimeFormat b = (TimeFormat) obj;
1✔
1646
            out.write(TIME_FORMAT);
1✔
1647
            serializeTimeFormat(out, b);
1✔
1648
        } else if (obj instanceof ZoneId) {
1✔
1649
            ZoneId b = (ZoneId) obj;
1✔
1650
            out.write(TIME_ZONE);
1✔
1651
            serializeTimeZone(out, b);
1✔
1652
        } else if (obj instanceof TimeStore) {
1✔
1653
            TimeStore b = (TimeStore) obj;
1✔
1654
            out.write(TIME_STORE);
1✔
1655
            serializeTimeStore(out);
1✔
1656
        } else if (obj instanceof ConfigurationImpl) {
1✔
1657
            ConfigurationImpl b = (ConfigurationImpl) obj;
1✔
1658
            out.write(CONFIGURATION);
1✔
1659
            serializeConfiguration(out);
1✔
1660
        } else if (obj instanceof Interval) {
1✔
1661
            Interval b = (Interval) obj;
1✔
1662
            out.write(INTERVAL);
1✔
1663
            serializeInterval(out, b);
1✔
1664
        } else if (obj instanceof List) {
1✔
1665
            List b = (List) obj;
1✔
1666
            out.write(LIST);
1✔
1667
            serializeList(out, b);
1✔
1668
        } else if (obj instanceof Set) {
1✔
1669
            Set b = (Set) obj;
1✔
1670
            out.write(SET);
1✔
1671
            serializeSet(out, b);
1✔
1672
        } else if (obj instanceof Map) {
1✔
1673
            Map b = (Map) obj;
1✔
1674
            out.write(MAP);
1✔
1675
            serializeMap(out, b);
1✔
1676
        } else if (obj instanceof Instant) {
1✔
1677
            Instant i = (Instant) obj;
1✔
1678
            out.write(INSTANT);
1✔
1679
            serializeInstant(out, i);
1✔
1680
        } else {
1✔
1681
            throw new IOException("No serialization handler for this class: " + clazz.getName());
×
1682
        }
1683
    }
1✔
1684

1685
    public static void serializeString(DataOutput out, String obj) throws IOException {
1686
        final int len = obj.length();
1✔
1687
        LongPacker.packInt(out, len);
1✔
1688
        for (int i = 0; i < len; i++) {
1✔
1689
            int c = (int) obj.charAt(i); // TODO investigate if c could be
1✔
1690
            // negative here
1691
            LongPacker.packInt(out, c);
1✔
1692
        }
1693
    }
1✔
1694

1695
    private void serializeByteArrayInt(DataOutput out, byte[] b) throws IOException {
1696
        LongPacker.packInt(out, b.length);
1✔
1697
        out.write(b);
1✔
1698
    }
1✔
1699

1700
    private void writeLongArray(DataOutput da, long[] obj) throws IOException {
1701
        long max = Long.MIN_VALUE;
1✔
1702
        long min = Long.MAX_VALUE;
1✔
1703
        for (long i : obj) {
1✔
1704
            max = Math.max(max, i);
1✔
1705
            min = Math.min(min, i);
1✔
1706
        }
1707

1708
        if (0 <= min && max <= 255) {
1✔
1709
            da.write(ARRAY_LONG_B);
1✔
1710
            LongPacker.packInt(da, obj.length);
1✔
1711
            for (long l : obj) {
1✔
1712
                da.write((int) l);
1✔
1713
            }
1714
        } else if (0 <= min && max <= Long.MAX_VALUE) {
1✔
1715
            da.write(ARRAY_LONG_PACKED);
1✔
1716
            LongPacker.packInt(da, obj.length);
1✔
1717
            for (long l : obj) {
1✔
1718
                LongPacker.packLong(da, l);
1✔
1719
            }
1720
        } else if (Short.MIN_VALUE <= min && max <= Short.MAX_VALUE) {
1✔
1721
            da.write(ARRAY_LONG_S);
1✔
1722
            LongPacker.packInt(da, obj.length);
1✔
1723
            for (long l : obj) {
1✔
1724
                da.writeShort((short) l);
1✔
1725
            }
1726
        } else if (Integer.MIN_VALUE <= min && max <= Integer.MAX_VALUE) {
1✔
1727
            da.write(ARRAY_LONG_I);
1✔
1728
            LongPacker.packInt(da, obj.length);
1✔
1729
            for (long l : obj) {
1✔
1730
                da.writeInt((int) l);
1✔
1731
            }
1732
        } else {
1733
            da.write(ARRAY_LONG_L);
1✔
1734
            LongPacker.packInt(da, obj.length);
1✔
1735
            for (long l : obj) {
1✔
1736
                da.writeLong(l);
1✔
1737
            }
1738
        }
1739
    }
1✔
1740

1741
    private void writeIntArray(DataOutput da, int[] obj) throws IOException {
1742
        int max = Integer.MIN_VALUE;
1✔
1743
        int min = Integer.MAX_VALUE;
1✔
1744
        for (int i : obj) {
1✔
1745
            max = Math.max(max, i);
1✔
1746
            min = Math.min(min, i);
1✔
1747
        }
1748

1749
        boolean fitsInByte = 0 <= min && max <= 255;
1✔
1750
        boolean fitsInShort = min >= Short.MIN_VALUE && max <= Short.MAX_VALUE;
1✔
1751

1752
        if (obj.length <= 255 && fitsInByte) {
1✔
1753
            da.write(ARRAY_INT_B_255);
1✔
1754
            da.write(obj.length);
1✔
1755
            for (int i : obj) {
1✔
1756
                da.write(i);
1✔
1757
            }
1758
        } else if (fitsInByte) {
1✔
1759
            da.write(ARRAY_INT_B_INT);
1✔
1760
            LongPacker.packInt(da, obj.length);
1✔
1761
            for (int i : obj) {
1✔
1762
                da.write(i);
1✔
1763
            }
1764
        } else if (0 <= min && max <= Integer.MAX_VALUE) {
1✔
1765
            da.write(ARRAY_INT_PACKED);
1✔
1766
            LongPacker.packInt(da, obj.length);
1✔
1767
            for (int l : obj) {
1✔
1768
                LongPacker.packInt(da, l);
1✔
1769
            }
1770
        } else if (fitsInShort) {
1✔
1771
            da.write(ARRAY_INT_S);
1✔
1772
            LongPacker.packInt(da, obj.length);
1✔
1773
            for (int i : obj) {
1✔
1774
                da.writeShort(i);
1✔
1775
            }
1776
        } else {
1777
            da.write(ARRAY_INT_I);
1✔
1778
            LongPacker.packInt(da, obj.length);
1✔
1779
            for (int i : obj) {
1✔
1780
                da.writeInt(i);
1✔
1781
            }
1782
        }
1783

1784
    }
1✔
1785

1786
    private void writeInteger(DataOutput da, final int val) throws IOException {
1787
        if (val == -1) {
1✔
1788
            da.write(INTEGER_MINUS_1);
1✔
1789
        } else if (val == 0) {
1✔
1790
            da.write(INTEGER_0);
1✔
1791
        } else if (val == 1) {
1✔
1792
            da.write(INTEGER_1);
1✔
1793
        } else if (val == 2) {
1✔
1794
            da.write(INTEGER_2);
1✔
1795
        } else if (val == 3) {
1✔
1796
            da.write(INTEGER_3);
1✔
1797
        } else if (val == 4) {
1✔
1798
            da.write(INTEGER_4);
1✔
1799
        } else if (val == 5) {
1✔
1800
            da.write(INTEGER_5);
1✔
1801
        } else if (val == 6) {
1✔
1802
            da.write(INTEGER_6);
1✔
1803
        } else if (val == 7) {
1✔
1804
            da.write(INTEGER_7);
1✔
1805
        } else if (val == 8) {
1✔
1806
            da.write(INTEGER_8);
1✔
1807
        } else if (val == Integer.MIN_VALUE) {
1✔
1808
            da.write(INTEGER_MINUS_MAX);
1✔
1809
        } else if (val > 0 && val < 255) {
1✔
1810
            da.write(INTEGER_255);
1✔
1811
            da.write(val);
1✔
1812
        } else if (val < 0) {
1✔
1813
            da.write(INTEGER_PACK_NEG);
1✔
1814
            LongPacker.packInt(da, -val);
1✔
1815
        } else {
1816
            da.write(INTEGER_PACK);
1✔
1817
            LongPacker.packInt(da, val);
1✔
1818
        }
1819
    }
1✔
1820

1821
    private void writeLong(DataOutput da, final long val) throws IOException {
1822
        if (val == -1) {
1✔
1823
            da.write(LONG_MINUS_1);
1✔
1824
        } else if (val == 0) {
1✔
1825
            da.write(LONG_0);
1✔
1826
        } else if (val == 1) {
1✔
1827
            da.write(LONG_1);
1✔
1828
        } else if (val == 2) {
1✔
1829
            da.write(LONG_2);
1✔
1830
        } else if (val == 3) {
1✔
1831
            da.write(LONG_3);
1✔
1832
        } else if (val == 4) {
1✔
1833
            da.write(LONG_4);
1✔
1834
        } else if (val == 5) {
1✔
1835
            da.write(LONG_5);
1✔
1836
        } else if (val == 6) {
1✔
1837
            da.write(LONG_6);
1✔
1838
        } else if (val == 7) {
1✔
1839
            da.write(LONG_7);
1✔
1840
        } else if (val == 8) {
1✔
1841
            da.write(LONG_8);
1✔
1842
        } else if (val == Long.MIN_VALUE) {
1✔
1843
            da.write(LONG_MINUS_MAX);
1✔
1844
        } else if (val > 0 && val < 255) {
1✔
1845
            da.write(LONG_255);
1✔
1846
            da.write((int) val);
1✔
1847
        } else if (val < 0) {
1✔
1848
            da.write(LONG_PACK_NEG);
1✔
1849
            LongPacker.packLong(da, -val);
1✔
1850
        } else {
1851
            da.write(LONG_PACK);
1✔
1852
            LongPacker.packLong(da, val);
1✔
1853
        }
1854
    }
1✔
1855

1856
    // DESERIALIZE PRIMITIVES
1857
    protected Object deserialize(byte[] buf) throws ClassNotFoundException, IOException {
1858
        DataInputOutput bs = new DataInputOutput(buf);
1✔
1859
        Object ret = deserialize(bs);
1✔
1860
        if (bs.available() != 0) {
1✔
1861
            throw new RuntimeException("bytes left: " + bs.available());
×
1862
        }
1863

1864
        return ret;
1✔
1865
    }
1866

1867
    protected Object deserialize(DataInput is) throws IOException, ClassNotFoundException {
1868
        Object ret = null;
1✔
1869

1870
        final int head = is.readUnsignedByte();
1✔
1871

1872
        switch (head) {
1✔
1873
            case NULL:
1874
                break;
1✔
1875
            case BOOLEAN_TRUE:
1876
                ret = Boolean.TRUE;
1✔
1877
                break;
1✔
1878
            case BOOLEAN_FALSE:
1879
                ret = Boolean.FALSE;
1✔
1880
                break;
1✔
1881
            case INTEGER_MINUS_1:
1882
                ret = -1;
1✔
1883
                break;
1✔
1884
            case INTEGER_0:
1885
                ret = 0;
1✔
1886
                break;
1✔
1887
            case INTEGER_1:
1888
                ret = 1;
1✔
1889
                break;
1✔
1890
            case INTEGER_2:
1891
                ret = 2;
1✔
1892
                break;
1✔
1893
            case INTEGER_3:
1894
                ret = 3;
1✔
1895
                break;
1✔
1896
            case INTEGER_4:
1897
                ret = 4;
1✔
1898
                break;
1✔
1899
            case INTEGER_5:
1900
                ret = 5;
1✔
1901
                break;
1✔
1902
            case INTEGER_6:
1903
                ret = 6;
1✔
1904
                break;
1✔
1905
            case INTEGER_7:
1906
                ret = 7;
1✔
1907
                break;
1✔
1908
            case INTEGER_8:
1909
                ret = 8;
1✔
1910
                break;
1✔
1911
            case INTEGER_MINUS_MAX:
1912
                ret = Integer.MIN_VALUE;
1✔
1913
                break;
1✔
1914
            case INTEGER_255:
1915
                ret = is.readUnsignedByte();
1✔
1916
                break;
1✔
1917
            case INTEGER_PACK_NEG:
1918
                ret = -LongPacker.unpackInt(is);
1✔
1919
                break;
1✔
1920
            case INTEGER_PACK:
1921
                ret = LongPacker.unpackInt(is);
1✔
1922
                break;
1✔
1923
            case LONG_MINUS_1:
1924
                ret = Long.valueOf(-1);
1✔
1925
                break;
1✔
1926
            case LONG_0:
1927
                ret = Long.valueOf(0);
1✔
1928
                break;
1✔
1929
            case LONG_1:
1930
                ret = Long.valueOf(1);
1✔
1931
                break;
1✔
1932
            case LONG_2:
1933
                ret = Long.valueOf(2);
1✔
1934
                break;
1✔
1935
            case LONG_3:
1936
                ret = Long.valueOf(3);
1✔
1937
                break;
1✔
1938
            case LONG_4:
1939
                ret = Long.valueOf(4);
1✔
1940
                break;
1✔
1941
            case LONG_5:
1942
                ret = Long.valueOf(5);
1✔
1943
                break;
1✔
1944
            case LONG_6:
1945
                ret = Long.valueOf(6);
1✔
1946
                break;
1✔
1947
            case LONG_7:
1948
                ret = Long.valueOf(7);
1✔
1949
                break;
1✔
1950
            case LONG_8:
1951
                ret = Long.valueOf(8);
1✔
1952
                break;
1✔
1953
            case LONG_255:
1954
                ret = Long.valueOf(is.readUnsignedByte());
1✔
1955
                break;
1✔
1956
            case LONG_PACK_NEG:
1957
                ret = -LongPacker.unpackLong(is);
1✔
1958
                break;
1✔
1959
            case LONG_PACK:
1960
                ret = LongPacker.unpackLong(is);
1✔
1961
                break;
1✔
1962
            case LONG_MINUS_MAX:
1963
                ret = Long.MIN_VALUE;
1✔
1964
                break;
1✔
1965
            case SHORT_MINUS_1:
1966
                ret = ((short) -1);
1✔
1967
                break;
1✔
1968
            case SHORT_0:
1969
                ret = ((short) 0);
1✔
1970
                break;
1✔
1971
            case SHORT_1:
1972
                ret = ((short) 1);
1✔
1973
                break;
1✔
1974
            case SHORT_255:
1975
                ret = ((short) is.readUnsignedByte());
1✔
1976
                break;
1✔
1977
            case SHORT_FULL:
1978
                ret = is.readShort();
1✔
1979
                break;
1✔
1980
            case BYTE_MINUS_1:
1981
                ret = ((byte) -1);
1✔
1982
                break;
1✔
1983
            case BYTE_0:
1984
                ret = ((byte) 0);
1✔
1985
                break;
1✔
1986
            case BYTE_1:
1987
                ret = ((byte) 1);
1✔
1988
                break;
1✔
1989
            case BYTE_FULL:
1990
                ret = (is.readByte());
1✔
1991
                break;
1✔
1992
            case SHORT_ARRAY:
1993
                int size = LongPacker.unpackInt(is);
1✔
1994
                ret = new short[size];
1✔
1995
                for (int i = 0; i < size; i++) {
1✔
1996
                    ((short[]) ret)[i] = is.readShort();
1✔
1997
                }
1998
                break;
1✔
1999
            case BOOLEAN_ARRAY:
2000
                size = LongPacker.unpackInt(is);
1✔
2001
                ret = new boolean[size];
1✔
2002
                for (int i = 0; i < size; i++) {
1✔
2003
                    ((boolean[]) ret)[i] = is.readBoolean();
1✔
2004
                }
2005
                break;
1✔
2006
            case DOUBLE_ARRAY:
2007
                size = LongPacker.unpackInt(is);
1✔
2008
                ret = new double[size];
1✔
2009
                for (int i = 0; i < size; i++) {
1✔
2010
                    ((double[]) ret)[i] = is.readDouble();
1✔
2011
                }
2012
                break;
1✔
2013
            case FLOAT_ARRAY:
2014
                size = LongPacker.unpackInt(is);
1✔
2015
                ret = new float[size];
1✔
2016
                for (int i = 0; i < size; i++) {
1✔
2017
                    ((float[]) ret)[i] = is.readFloat();
1✔
2018
                }
2019
                break;
1✔
2020
            case CHAR_ARRAY:
2021
                size = LongPacker.unpackInt(is);
1✔
2022
                ret = new char[size];
1✔
2023
                for (int i = 0; i < size; i++) {
1✔
2024
                    ((char[]) ret)[i] = (char) is.readUnsignedShort();
1✔
2025
                }
2026
                break;
1✔
2027
            case CHAR:
2028
                ret = Character.valueOf((char) is.readUnsignedShort());
1✔
2029
                break;
1✔
2030
            case FLOAT_MINUS_1:
2031
                ret = Float.valueOf(-1);
1✔
2032
                break;
1✔
2033
            case FLOAT_0:
2034
                ret = Float.valueOf(0);
1✔
2035
                break;
1✔
2036
            case FLOAT_1:
2037
                ret = Float.valueOf(1);
1✔
2038
                break;
1✔
2039
            case FLOAT_255:
2040
                ret = Float.valueOf(is.readUnsignedByte());
1✔
2041
                break;
1✔
2042
            case FLOAT_SHORT:
2043
                ret = Float.valueOf(is.readShort());
1✔
2044
                break;
1✔
2045
            case FLOAT_FULL:
2046
                ret = is.readFloat();
1✔
2047
                break;
1✔
2048
            case DOUBLE_MINUS_1:
2049
                ret = Double.valueOf(-1);
1✔
2050
                break;
1✔
2051
            case DOUBLE_0:
2052
                ret = Double.valueOf(0);
1✔
2053
                break;
1✔
2054
            case DOUBLE_1:
2055
                ret = Double.valueOf(1);
1✔
2056
                break;
1✔
2057
            case DOUBLE_255:
2058
                ret = Double.valueOf(is.readUnsignedByte());
1✔
2059
                break;
1✔
2060
            case DOUBLE_SHORT:
2061
                ret = Double.valueOf(is.readShort());
1✔
2062
                break;
1✔
2063
            case DOUBLE_FULL:
2064
                ret = is.readDouble();
1✔
2065
                break;
1✔
2066
            case BIGINTEGER:
2067
                ret = new BigInteger(deserializeArrayByteInt(is));
1✔
2068
                break;
1✔
2069
            case BIGDECIMAL:
2070
                ret = new BigDecimal(new BigInteger(deserializeArrayByteInt(is)), LongPacker.unpackInt(is));
1✔
2071
                break;
1✔
2072
            case STRING:
2073
                ret = deserializeString(is);
1✔
2074
                break;
1✔
2075
            case STRING_EMPTY:
2076
                ret = EMPTY_STRING;
1✔
2077
                break;
1✔
2078
            case CLASS:
2079
                ret = deserializeClass(is);
1✔
2080
                break;
1✔
2081
            case DATE:
2082
                ret = new Date(is.readLong());
1✔
2083
                break;
1✔
2084
            case ARRAY_INT_B_255:
2085
                ret = deserializeArrayIntB255(is);
1✔
2086
                break;
1✔
2087
            case ARRAY_INT_B_INT:
2088
                ret = deserializeArrayIntBInt(is);
1✔
2089
                break;
1✔
2090
            case ARRAY_INT_S:
2091
                ret = deserializeArrayIntSInt(is);
1✔
2092
                break;
1✔
2093
            case ARRAY_INT_I:
2094
                ret = deserializeArrayIntIInt(is);
1✔
2095
                break;
1✔
2096
            case ARRAY_INT_PACKED:
2097
                ret = deserializeArrayIntPack(is);
1✔
2098
                break;
1✔
2099
            case ARRAY_LONG_B:
2100
                ret = deserializeArrayLongB(is);
1✔
2101
                break;
1✔
2102
            case ARRAY_LONG_S:
2103
                ret = deserializeArrayLongS(is);
1✔
2104
                break;
1✔
2105
            case ARRAY_LONG_I:
2106
                ret = deserializeArrayLongI(is);
1✔
2107
                break;
1✔
2108
            case ARRAY_LONG_L:
2109
                ret = deserializeArrayLongL(is);
1✔
2110
                break;
1✔
2111
            case ARRAY_LONG_PACKED:
2112
                ret = deserializeArrayLongPack(is);
1✔
2113
                break;
1✔
2114
            case ARRAY_BYTE_INT:
2115
                ret = deserializeArrayByteInt(is);
1✔
2116
                break;
1✔
2117
            case STRING_ARRAY:
2118
                ret = deserializeStringArray(is);
1✔
2119
                break;
1✔
2120
            case ARRAY_OBJECT:
2121
                ret = deserializeArrayObject(is);
1✔
2122
                break;
1✔
2123
            case TIMESTAMP_SET:
2124
                ret = deserializeTimestampSet(is);
1✔
2125
                break;
1✔
2126
            case INTERVAL_SET:
2127
                ret = deserializeIntervalSet(is);
1✔
2128
                break;
1✔
2129
            case NODE:
2130
                ret = deserializeNode(is);
1✔
2131
                break;
1✔
2132
            case EDGE:
2133
                ret = deserializeEdge(is);
1✔
2134
                break;
1✔
2135
            case EDGETYPE_STORE:
2136
                ret = deserializeEdgeTypeStore(is);
1✔
2137
                break;
1✔
2138
            case COLUMN_ORIGIN:
2139
                ret = Origin.valueOf((String) deserialize(is));
1✔
2140
                break;
1✔
2141
            case TABLE:
2142
                ret = deserializeTable(is);
1✔
2143
                break;
1✔
2144
            case GRAPH_STORE:
2145
                ret = deserializeGraphStore(is);
1✔
2146
                break;
1✔
2147
            case GRAPH_FACTORY:
2148
                ret = deserializeGraphFactory(is);
1✔
2149
                break;
1✔
2150
            case GRAPH_VIEW_STORE:
2151
                ret = deserializeViewStore(is);
1✔
2152
                break;
1✔
2153
            case GRAPH_VIEW:
2154
                ret = deserializeGraphView(is);
1✔
2155
                break;
1✔
2156
            case BIT_VECTOR:
2157
                ret = deserializeBitSet(is);
1✔
2158
                break;
1✔
2159
            case GRAPH_STORE_CONFIGURATION:
2160
                ret = deserializeGraphStoreConfiguration(is);
1✔
2161
                break;
1✔
2162
            case GRAPH_VERSION:
2163
                ret = deserializeGraphVersion(is);
1✔
2164
                break;
1✔
2165
            case NODE_PROPERTIES:
2166
                ret = deserializeNodeProperties(is);
1✔
2167
                break;
1✔
2168
            case EDGE_PROPERTIES:
2169
                ret = deserializeEdgeProperties(is);
1✔
2170
                break;
1✔
2171
            case TEXT_PROPERTIES:
2172
                ret = deserializeTextProperties(is);
1✔
2173
                break;
1✔
2174
            case ESTIMATOR:
2175
                ret = Estimator.valueOf(deserializeString(is));
1✔
2176
                break;
1✔
2177
            case TIME_REPRESENTATION:
2178
                ret = TimeRepresentation.valueOf(deserializeString(is));
1✔
2179
                break;
1✔
2180
            case TIMESTAMP_MAP:
2181
                ret = deserializeTimestampMap(is);
1✔
2182
                break;
1✔
2183
            case INTERVAL_MAP:
2184
                ret = deserializeIntervalMap(is);
1✔
2185
                break;
1✔
2186
            case TIMESTAMP_INDEX_STORE:
2187
                ret = deserializeTimestampIndexStore(is);
1✔
2188
                break;
1✔
2189
            case INTERVAL_INDEX_STORE:
2190
                ret = deserializeIntervalIndexStore(is);
1✔
2191
                break;
1✔
2192
            case GRAPH_ATTRIBUTES:
2193
                ret = deserializeGraphAttributes(is);
1✔
2194
                break;
1✔
2195
            case TIME_FORMAT:
2196
                ret = deserializeTimeFormat(is);
1✔
2197
                break;
1✔
2198
            case TIME_ZONE:
2199
                ret = deserializeTimeZone(is);
1✔
2200
                break;
1✔
2201
            case TIME_STORE:
2202
                ret = deserializeTimeStore(is);
1✔
2203
                break;
1✔
2204
            case CONFIGURATION:
2205
                ret = deserializeConfiguration(is);
1✔
2206
                break;
1✔
2207
            case INTERVAL:
2208
                ret = deserializeInterval(is);
1✔
2209
                break;
1✔
2210
            case LIST:
2211
                ret = deserializeList(is);
1✔
2212
                break;
1✔
2213
            case SET:
2214
                ret = deserializeSet(is);
1✔
2215
                break;
1✔
2216
            case MAP:
2217
                ret = deserializeMap(is);
1✔
2218
                break;
1✔
2219
            case INSTANT:
2220
                ret = deserializeInstant(is);
1✔
2221
                break;
1✔
2222
            default:
NEW
2223
                throw new IOException("Unknown serialization type tag: " + head);
×
2224
        }
2225
        return ret;
1✔
2226
    }
2227

2228
    public static String deserializeString(DataInput buf) throws IOException {
2229
        int len = LongPacker.unpackInt(buf);
1✔
2230
        char[] b = new char[len];
1✔
2231
        for (int i = 0; i < len; i++) {
1✔
2232
            b[i] = (char) LongPacker.unpackInt(buf);
1✔
2233
        }
2234

2235
        return new String(b);
1✔
2236
    }
2237

2238
    private Class deserializeClass(DataInput is) throws IOException, ClassNotFoundException {
2239
        String className = (String) deserialize(is);
1✔
2240
        Class cls = Class.forName(className);
1✔
2241
        return cls;
1✔
2242
    }
2243

2244
    private byte[] deserializeArrayByteInt(DataInput is) throws IOException {
2245
        int size = LongPacker.unpackInt(is);
1✔
2246
        byte[] b = new byte[size];
1✔
2247
        is.readFully(b);
1✔
2248
        return b;
1✔
2249
    }
2250

2251
    private long[] deserializeArrayLongL(DataInput is) throws IOException {
2252
        int size = LongPacker.unpackInt(is);
1✔
2253
        long[] ret = new long[size];
1✔
2254
        for (int i = 0; i < size; i++) {
1✔
2255
            ret[i] = is.readLong();
1✔
2256
        }
2257
        return ret;
1✔
2258
    }
2259

2260
    private long[] deserializeArrayLongI(DataInput is) throws IOException {
2261
        int size = LongPacker.unpackInt(is);
1✔
2262
        long[] ret = new long[size];
1✔
2263
        for (int i = 0; i < size; i++) {
1✔
2264
            ret[i] = is.readInt();
1✔
2265
        }
2266
        return ret;
1✔
2267
    }
2268

2269
    private long[] deserializeArrayLongS(DataInput is) throws IOException {
2270
        int size = LongPacker.unpackInt(is);
1✔
2271
        long[] ret = new long[size];
1✔
2272
        for (int i = 0; i < size; i++) {
1✔
2273
            ret[i] = is.readShort();
1✔
2274
        }
2275
        return ret;
1✔
2276
    }
2277

2278
    private long[] deserializeArrayLongB(DataInput is) throws IOException {
2279
        int size = LongPacker.unpackInt(is);
1✔
2280
        long[] ret = new long[size];
1✔
2281
        for (int i = 0; i < size; i++) {
1✔
2282
            ret[i] = is.readUnsignedByte();
1✔
2283
            if (ret[i] < 0) {
1✔
2284
                throw new EOFException();
×
2285
            }
2286
        }
2287
        return ret;
1✔
2288
    }
2289

2290
    private int[] deserializeArrayIntIInt(DataInput is) throws IOException {
2291
        int size = LongPacker.unpackInt(is);
1✔
2292
        int[] ret = new int[size];
1✔
2293
        for (int i = 0; i < size; i++) {
1✔
2294
            ret[i] = is.readInt();
1✔
2295
        }
2296
        return ret;
1✔
2297
    }
2298

2299
    private int[] deserializeArrayIntSInt(DataInput is) throws IOException {
2300
        int size = LongPacker.unpackInt(is);
1✔
2301
        int[] ret = new int[size];
1✔
2302
        for (int i = 0; i < size; i++) {
1✔
2303
            ret[i] = is.readShort();
1✔
2304
        }
2305
        return ret;
1✔
2306
    }
2307

2308
    private int[] deserializeArrayIntBInt(DataInput is) throws IOException {
2309
        int size = LongPacker.unpackInt(is);
1✔
2310
        int[] ret = new int[size];
1✔
2311
        for (int i = 0; i < size; i++) {
1✔
2312
            ret[i] = is.readUnsignedByte();
1✔
2313
            if (ret[i] < 0) {
1✔
2314
                throw new EOFException();
×
2315
            }
2316
        }
2317
        return ret;
1✔
2318
    }
2319

2320
    private int[] deserializeArrayIntPack(DataInput is) throws IOException {
2321
        int size = LongPacker.unpackInt(is);
1✔
2322
        if (size < 0) {
1✔
2323
            throw new EOFException();
×
2324
        }
2325

2326
        int[] ret = new int[size];
1✔
2327
        for (int i = 0; i < size; i++) {
1✔
2328
            ret[i] = LongPacker.unpackInt(is);
1✔
2329
        }
2330
        return ret;
1✔
2331
    }
2332

2333
    private long[] deserializeArrayLongPack(DataInput is) throws IOException {
2334
        int size = LongPacker.unpackInt(is);
1✔
2335
        if (size < 0) {
1✔
2336
            throw new EOFException();
×
2337
        }
2338

2339
        long[] ret = new long[size];
1✔
2340
        for (int i = 0; i < size; i++) {
1✔
2341
            ret[i] = LongPacker.unpackLong(is);
1✔
2342
        }
2343
        return ret;
1✔
2344
    }
2345

2346
    private int[] deserializeArrayIntB255(DataInput is) throws IOException {
2347
        int size = is.readUnsignedByte();
1✔
2348
        if (size < 0) {
1✔
2349
            throw new EOFException();
×
2350
        }
2351

2352
        int[] ret = new int[size];
1✔
2353
        for (int i = 0; i < size; i++) {
1✔
2354
            ret[i] = is.readUnsignedByte();
1✔
2355
            if (ret[i] < 0) {
1✔
2356
                throw new EOFException();
×
2357
            }
2358
        }
2359
        return ret;
1✔
2360
    }
2361

2362
    private String[] deserializeStringArray(DataInput is) throws IOException, ClassNotFoundException {
2363
        int size = LongPacker.unpackInt(is);
1✔
2364

2365
        String[] s = (String[]) Array.newInstance(String.class, size);
1✔
2366
        for (int i = 0; i < size; i++) {
1✔
2367
            s[i] = deserializeString(is);
1✔
2368
        }
2369
        return s;
1✔
2370

2371
    }
2372

2373
    private Object[] deserializeArrayObject(DataInput is) throws IOException, ClassNotFoundException {
2374
        int size = LongPacker.unpackInt(is);
1✔
2375

2376
        Object[] s = (Object[]) Array.newInstance(Object.class, size);
1✔
2377
        for (int i = 0; i < size; i++) {
1✔
2378
            s[i] = deserialize(is);
1✔
2379
        }
2380
        return s;
1✔
2381

2382
    }
2383

2384
    protected static class GraphStoreConfigurationVersion {
2385

2386
        protected final boolean enableElementLabel;
2387
        protected final boolean enableElementTimestamp;
2388
        protected final boolean enableNodeProperties;
2389
        protected final boolean enableEdgeProperties;
2390

2391
        public GraphStoreConfigurationVersion(boolean enableElementLabel, boolean enableElementTimestamp, boolean enableNodeProperties, boolean enableEdgeProperties) {
1✔
2392
            this.enableElementLabel = enableElementLabel;
1✔
2393
            this.enableElementTimestamp = enableElementTimestamp;
1✔
2394
            this.enableNodeProperties = enableNodeProperties;
1✔
2395
            this.enableEdgeProperties = enableEdgeProperties;
1✔
2396
        }
1✔
2397
    }
2398
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc