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

gephi / graphstore / #574

25 Aug 2026 11:52AM UTC coverage: 91.211% (+0.004%) from 91.207%
#574

push

web-flow
Close graph-lock gaps in GraphModel.Serialization (#289)

* Hold the graph read lock for the entire duration of serializeGraphStore

Previously the only locking came incidentally from NodeStore/EdgeStore
iterators, which release the lock between the node and edge loops and
leave the configuration/columns/time store/views sections unprotected,
so a serialized graph could observe a torn state under concurrent
mutation.

* Hold the graph write lock for the entire duration of deserializeGraphStore

deserializeNode/deserializeEdge write directly into NodeStore/EdgeStore,
bypassing GraphStore's own auto-locked addNode()/addEdge(), so
deserialization had no lock coverage at all and could race with a
concurrent reader on the same graph model.

* Cleanup

44 of 45 new or added lines in 1 file covered. (97.78%)

11789 of 12925 relevant lines covered (91.21%)

0.91 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

301
    public void serializeGraphStore(DataOutput out, GraphStore store) throws IOException {
302
        // Hold the read lock for the whole method so the write is atomic with respect to
303
        // concurrent structural mutation.
304
        store.autoReadLock();
1✔
305
        try {
306
            // Configuration
307
            serializeGraphStoreConfiguration(out);
1✔
308

309
            // GraphVersion
310
            serialize(out, store.version);
1✔
311

312
            // Edge types
313
            EdgeTypeStore edgeTypeStore = store.edgeTypeStore;
1✔
314
            serialize(out, edgeTypeStore);
1✔
315

316
            // Column
317
            serialize(out, store.nodeTable);
1✔
318
            serialize(out, store.edgeTable);
1✔
319

320
            // Time store
321
            serialize(out, store.timeStore);
1✔
322

323
            // Factory
324
            serialize(out, store.factory);
1✔
325

326
            // Atts
327
            serialize(out, store.attributes);
1✔
328

329
            // TimeFormat
330
            serialize(out, store.timeFormat);
1✔
331

332
            // Time zone
333
            serialize(out, store.timeZone);
1✔
334

335
            // Nodes + Edges
336
            int nodesAndEdges = store.nodeStore.size() + store.edgeStore.size();
1✔
337
            serialize(out, nodesAndEdges);
1✔
338

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

346
            // Views
347
            serialize(out, store.viewStore);
1✔
348
        } finally {
349
            store.autoReadUnlock();
1✔
350
        }
351
    }
1✔
352

353
    public GraphStore deserializeGraphStore(DataInput is) throws IOException, ClassNotFoundException {
354
        GraphStore store = model.store;
1✔
355
        // Hold the write lock for the whole method: deserialization mutates the store directly
356
        store.autoWriteLock();
1✔
357
        try {
358
            if (!store.nodeStore.isEmpty()) { // TODO test other stores
1✔
NEW
359
                throw new IOException("The store is not empty");
×
360
            }
361

362
            idMap.clear();
1✔
363

364
            // Store Configuration
365
            deserialize(is);
1✔
366

367
            // Graph Version
368
            GraphVersion version = (GraphVersion) deserialize(is);
1✔
369
            store.version.nodeVersion = version.nodeVersion;
1✔
370
            store.version.edgeVersion = version.edgeVersion;
1✔
371

372
            // Edge types
373
            deserialize(is);
1✔
374

375
            // Columns
376
            deserialize(is);
1✔
377
            deserialize(is);
1✔
378

379
            // Time store
380
            deserialize(is);
1✔
381

382
            // Factory
383
            deserialize(is);
1✔
384

385
            // Atts
386
            GraphAttributesImpl attributes = (GraphAttributesImpl) deserialize(is);
1✔
387
            store.attributes.setGraphAttributes(attributes);
1✔
388

389
            // TimeFormat
390
            deserialize(is);
1✔
391

392
            // Time zone
393
            deserialize(is);
1✔
394

395
            // Nodes and edges
396
            int nodesAndEdges = (Integer) deserialize(is);
1✔
397
            for (int i = 0; i < nodesAndEdges; i++) {
1✔
398
                deserialize(is);
1✔
399
            }
400

401
            // ViewStore
402
            deserialize(is);
1✔
403

404
            return store;
1✔
405
        } finally {
406
            store.autoWriteUnlock();
1✔
407
        }
408
    }
409

410
    private void serializeNode(DataOutput out, NodeImpl node) throws IOException {
411
        serialize(out, node.getId());
1✔
412
        serialize(out, node.storeId);
1✔
413
        serialize(out, node.attributes.attributes);
1✔
414
        serialize(out, node.properties);
1✔
415
    }
1✔
416

417
    private void serializeEdge(DataOutput out, EdgeImpl edge) throws IOException {
418
        serialize(out, edge.getId());
1✔
419
        serialize(out, edge.source.storeId);
1✔
420
        serialize(out, edge.target.storeId);
1✔
421
        serialize(out, edge.type);
1✔
422
        if (edge.graphStore != null && edge.hasDynamicWeight()) {
1✔
423
            serialize(out, edge.getWeight());
1✔
424
        } else {
425
            serialize(out, GraphStoreConfiguration.DEFAULT_EDGE_WEIGHT);
1✔
426
        }
427
        serialize(out, edge.isDirected());
1✔
428
        serialize(out, edge.attributes.attributes);
1✔
429
        serialize(out, edge.properties);
1✔
430
    }
1✔
431

432
    private NodeImpl deserializeNode(DataInput is) throws IOException, ClassNotFoundException {
433
        Object id = deserialize(is);
1✔
434
        int storeId = (Integer) deserialize(is);
1✔
435
        Object[] attributes = (Object[]) deserialize(is);
1✔
436
        NodePropertiesImpl properties = (NodePropertiesImpl) deserialize(is);
1✔
437

438
        NodeImpl node = (NodeImpl) model.store.factory.newNode(id);
1✔
439
        node.attributes.setBackingArray(attributes);
1✔
440
        if (node.properties != null) {
1✔
441
            node.setNodeProperties(properties);
1✔
442
        }
443
        model.store.nodeStore.add(node);
1✔
444

445
        idMap.put(storeId, node.storeId);
1✔
446

447
        return node;
1✔
448
    }
449

450
    private EdgeImpl deserializeEdge(DataInput is) throws IOException, ClassNotFoundException {
451
        Object id = deserialize(is);
1✔
452
        int sourceId = (Integer) deserialize(is);
1✔
453
        int targetId = (Integer) deserialize(is);
1✔
454
        int type = (Integer) deserialize(is);
1✔
455
        double weight = (Double) deserialize(is);
1✔
456
        boolean directed = (Boolean) deserialize(is);
1✔
457
        Object[] attributes = (Object[]) deserialize(is);
1✔
458
        EdgePropertiesImpl properties = (EdgePropertiesImpl) deserialize(is);
1✔
459

460
        int sourceNewId = idMap.get(sourceId);
1✔
461
        int targetNewId = idMap.get(targetId);
1✔
462

463
        if (sourceNewId == NULL_ID || targetNewId == NULL_ID) {
1✔
464
            throw new IOException("The edge source or target can't be found");
×
465
        }
466

467
        NodeImpl source = model.store.nodeStore.get(sourceNewId);
1✔
468
        NodeImpl target = model.store.nodeStore.get(targetNewId);
1✔
469

470
        EdgeImpl edge = (EdgeImpl) model.store.factory.newEdge(id, source, target, type, weight, directed);
1✔
471
        edge.attributes.setBackingArray(attributes);
1✔
472
        if (edge.properties != null) {
1✔
473
            edge.setEdgeProperties(properties);
1✔
474
        }
475

476
        model.store.edgeStore.add(edge);
1✔
477

478
        return edge;
1✔
479
    }
480

481
    private void serializeEdgeTypeStore(final DataOutput out) throws IOException {
482
        EdgeTypeStore edgeTypeStore = model.store.edgeTypeStore;
1✔
483
        int length = edgeTypeStore.length;
1✔
484
        serialize(out, length);
1✔
485
        short[] ids = edgeTypeStore.getIds();
1✔
486
        serialize(out, ids);
1✔
487
        Object[] labels = edgeTypeStore.getLabels();
1✔
488
        serialize(out, labels);
1✔
489
        short[] garbage = edgeTypeStore.getGarbage();
1✔
490
        serialize(out, garbage);
1✔
491
    }
1✔
492

493
    private EdgeTypeStore deserializeEdgeTypeStore(final DataInput is) throws IOException, ClassNotFoundException {
494
        int length = (Integer) deserialize(is);
1✔
495
        short[] ids = (short[]) deserialize(is);
1✔
496
        Object[] labels = (Object[]) deserialize(is);
1✔
497
        short[] garbage = (short[]) deserialize(is);
1✔
498

499
        EdgeTypeStore edgeTypeStore = model.store.edgeTypeStore;
1✔
500
        edgeTypeStore.length = length;
1✔
501
        for (int i = 0; i < ids.length; i++) {
1✔
502
            short id = ids[i];
1✔
503
            Object label = labels[i];
1✔
504
            edgeTypeStore.idMap.put(id, label);
1✔
505
            edgeTypeStore.labelMap.put(label, id);
1✔
506
        }
507
        for (int i = 0; i < garbage.length; i++) {
1✔
508
            edgeTypeStore.garbageQueue.add(garbage[i]);
1✔
509
        }
510
        return edgeTypeStore;
1✔
511
    }
512

513
    private void serializeTable(final DataOutput out, final TableImpl table) throws IOException {
514
        serialize(out, table.store.elementType);
1✔
515

516
        serializeColumnStore(out, table.store);
1✔
517
    }
1✔
518

519
    private TableImpl deserializeTable(final DataInput is) throws IOException, ClassNotFoundException {
520
        Class elementType = (Class) deserialize(is);
1✔
521

522
        TableImpl table = null;
1✔
523

524
        if (elementType.equals(Node.class)) {
1✔
525
            table = model.store.nodeTable;
1✔
526
        } else if (elementType.equals(Edge.class)) {
1✔
527
            table = model.store.edgeTable;
1✔
528
        } else {
529
            throw new RuntimeException("Not recognized column store");
×
530
        }
531

532
        deserializeColumnStore(is, table);
1✔
533

534
        return table;
1✔
535
    }
536

537
    private void serializeColumnStore(final DataOutput out, final ColumnStore columnStore) throws IOException {
538
        int length = columnStore.length;
1✔
539
        serialize(out, length);
1✔
540

541
        for (int i = 0; i < length; i++) {
1✔
542
            ColumnImpl col = columnStore.columns[i];
1✔
543
            serializeColumn(out, col);
1✔
544
        }
545

546
        serialize(out, columnStore.garbageQueue.toShortArray());
1✔
547
    }
1✔
548

549
    private ColumnStore deserializeColumnStore(final DataInput is, final TableImpl table) throws IOException, ClassNotFoundException {
550
        ColumnStore columnStore = table.store;
1✔
551
        int length = (Integer) deserialize(is);
1✔
552
        columnStore.length = length;
1✔
553

554
        for (int i = 0; i < length; i++) {
1✔
555
            ColumnImpl col = (ColumnImpl) deserializeColumn(is, table);
1✔
556
            if (col != null) {
1✔
557
                columnStore.columns[col.storeId] = col;
1✔
558
                columnStore.idMap.put(col.id, columnStore.intToShort(col.storeId));
1✔
559
                if (columnStore.indexStore != null) {
1✔
560
                    columnStore.indexStore.addColumn(col);
1✔
561
                }
562
            }
563
        }
564

565
        short[] garbage = (short[]) deserialize(is);
1✔
566
        for (int i = 0; i < garbage.length; i++) {
1✔
567
            columnStore.garbageQueue.add(garbage[i]);
1✔
568
        }
569
        return columnStore;
1✔
570
    }
571

572
    private void serializeColumn(final DataOutput out, final ColumnImpl column) throws IOException {
573
        if (column == null) {
1✔
574
            serialize(out, null);
1✔
575
            return;
1✔
576
        }
577
        serialize(out, column.id);
1✔
578
        serialize(out, column.title);
1✔
579
        serialize(out, column.origin);
1✔
580
        serialize(out, column.storeId);
1✔
581
        serialize(out, column.typeClass);
1✔
582
        serialize(out, column.defaultValue);
1✔
583
        serialize(out, column.indexed);
1✔
584
        serialize(out, column.readOnly);
1✔
585
        serialize(out, column.estimator);
1✔
586
    }
1✔
587

588
    private ColumnImpl deserializeColumn(final DataInput is, TableImpl table) throws IOException, ClassNotFoundException {
589
        String id = (String) deserialize(is);
1✔
590
        if (id == null) {
1✔
591
            return null;
1✔
592
        }
593
        String title = (String) deserialize(is);
1✔
594
        Origin origin = (Origin) deserialize(is);
1✔
595
        int storeId = (Integer) deserialize(is);
1✔
596
        Class typeClass = (Class) deserialize(is);
1✔
597
        Object defaultValue = deserialize(is);
1✔
598
        boolean indexed = (Boolean) deserialize(is);
1✔
599
        boolean readOnly = (Boolean) deserialize(is);
1✔
600
        Estimator estimator = (Estimator) deserialize(is);
1✔
601

602
        ColumnImpl column = model.store.defaultColumns.getColumn(table, storeId);
1✔
603
        if (column == null) {
1✔
604
            column = new ColumnImpl(table, (String) id, typeClass, title, defaultValue, origin, indexed, readOnly);
1✔
605
            column.storeId = storeId;
1✔
606
        }
607

608
        if (estimator != null) {
1✔
609
            column.setEstimator(estimator);
1✔
610
        }
611

612
        return column;
1✔
613
    }
614

615
    private void serializeGraphFactory(final DataOutput out) throws IOException {
616
        GraphFactoryImpl factory = model.store.factory;
1✔
617

618
        serialize(out, factory.getNodeCounter());
1✔
619
        serialize(out, factory.getEdgeCounter());
1✔
620
    }
1✔
621

622
    private GraphFactoryImpl deserializeGraphFactory(final DataInput is) throws IOException, ClassNotFoundException {
623
        GraphFactoryImpl graphFactory = model.store.factory;
1✔
624

625
        int nodeCounter = (Integer) deserialize(is);
1✔
626
        int edgeCounter = (Integer) deserialize(is);
1✔
627

628
        graphFactory.setNodeCounter(nodeCounter);
1✔
629
        graphFactory.setEdgeCounter(edgeCounter);
1✔
630

631
        return graphFactory;
1✔
632
    }
633

634
    private void serializeViewStore(final DataOutput out) throws IOException {
635
        GraphViewStore viewStore = model.store.viewStore;
1✔
636

637
        serialize(out, viewStore.length);
1✔
638
        serialize(out, viewStore.views);
1✔
639
        serialize(out, viewStore.garbageQueue.toIntArray());
1✔
640
    }
1✔
641

642
    private GraphViewStore deserializeViewStore(final DataInput is) throws IOException, ClassNotFoundException {
643
        GraphViewStore viewStore = model.store.viewStore;
1✔
644

645
        int length = (Integer) deserialize(is);
1✔
646
        Object[] views = (Object[]) deserialize(is);
1✔
647
        int[] garbages = (int[]) deserialize(is);
1✔
648

649
        viewStore.length = length;
1✔
650
        viewStore.views = new GraphViewImpl[views.length];
1✔
651
        System.arraycopy(views, 0, viewStore.views, 0, views.length);
1✔
652
        for (int i = 0; i < garbages.length; i++) {
1✔
653
            viewStore.garbageQueue.add(garbages[i]);
1✔
654
        }
655
        return viewStore;
1✔
656
    }
657

658
    private void serializeGraphView(final DataOutput out, final GraphViewImpl view) throws IOException {
659
        serialize(out, view.nodeView);
1✔
660
        serialize(out, view.edgeView);
1✔
661
        serialize(out, view.storeId);
1✔
662
        serialize(out, view.nodeCount);
1✔
663
        serialize(out, view.edgeCount);
1✔
664

665
        serialize(out, view.nodeBitVector);
1✔
666
        serialize(out, view.edgeBitVector);
1✔
667

668
        serialize(out, view.typeCounts);
1✔
669
        serialize(out, view.mutualEdgeTypeCounts);
1✔
670
        serialize(out, view.mutualEdgesCount);
1✔
671

672
        serialize(out, view.version);
1✔
673

674
        serialize(out, view.attributes);
1✔
675
        serialize(out, view.interval);
1✔
676
    }
1✔
677

678
    private GraphViewImpl deserializeGraphView(final DataInput is) throws IOException, ClassNotFoundException {
679
        boolean nodeView = (Boolean) deserialize(is);
1✔
680
        boolean edgeView = (Boolean) deserialize(is);
1✔
681
        GraphViewImpl view = new GraphViewImpl(model.store, nodeView, edgeView);
1✔
682

683
        int storeId = (Integer) deserialize(is);
1✔
684
        int nodeCount = (Integer) deserialize(is);
1✔
685
        int edgeCount = (Integer) deserialize(is);
1✔
686
        BitSet nodeCountVector = (BitSet) deserialize(is);
1✔
687
        BitSet edgeCountVector = (BitSet) deserialize(is);
1✔
688
        int[] typeCounts = (int[]) deserialize(is);
1✔
689
        int[] mutualEdgeTypeCounts = (int[]) deserialize(is);
1✔
690
        int mutualEdgesCount = (Integer) deserialize(is);
1✔
691
        GraphVersion version = (GraphVersion) deserialize(is);
1✔
692
        GraphAttributesImpl atts = (GraphAttributesImpl) deserialize(is);
1✔
693
        Interval interval = (Interval) deserialize(is);
1✔
694

695
        view.nodeCount = nodeCount;
1✔
696
        view.edgeCount = edgeCount;
1✔
697
        view.nodeBitVector = nodeCountVector;
1✔
698
        view.edgeBitVector = edgeCountVector;
1✔
699
        view.storeId = storeId;
1✔
700

701
        view.typeCounts = typeCounts;
1✔
702
        view.mutualEdgesCount = mutualEdgesCount;
1✔
703
        view.mutualEdgeTypeCounts = mutualEdgeTypeCounts;
1✔
704

705
        view.version.nodeVersion = version.nodeVersion;
1✔
706
        view.version.edgeVersion = version.edgeVersion;
1✔
707

708
        view.attributes.setGraphAttributes(atts);
1✔
709
        view.interval = interval;
1✔
710

711
        return view;
1✔
712
    }
713

714
    // Made compatible with legacy BitVector serialization, which was in place until
715
    // version 0.8.1
716
    public void serializeBitSet(final DataOutput out, final BitSet bitSet) throws IOException {
717
        // BitSet.length() returns the index of the highest set bit + 1
718
        // This gives us the logical size (0 if empty)
719
        int size = bitSet.length();
1✔
720

721
        serialize(out, size);
1✔
722

723
        // Get the long array from BitSet
724
        long[] words = bitSet.toLongArray();
1✔
725

726
        // Calculate how many longs BitVector would use for this size
727
        int requiredLongs = (size + 63) / 64;
1✔
728

729
        // Create array with the exact required size (matching BitVector format)
730
        long[] elements = new long[requiredLongs];
1✔
731

732
        // Copy the BitSet data
733
        System.arraycopy(words, 0, elements, 0, Math.min(words.length, requiredLongs));
1✔
734

735
        serialize(out, elements);
1✔
736
    }
1✔
737

738
    public BitSet deserializeBitSet(final DataInput is) throws IOException, ClassNotFoundException {
739
        int size = (Integer) deserialize(is);
1✔
740
        long[] elements = (long[]) deserialize(is);
1✔
741

742
        // BitSet.valueOf() handles the long array correctly
743
        return BitSet.valueOf(elements);
1✔
744
    }
745

746
    private void serializeGraphStoreConfiguration(final DataOutput out) throws IOException {
747
        out.write(GRAPH_STORE_CONFIGURATION);
1✔
748
        serialize(out, GraphStoreConfiguration.ENABLE_ELEMENT_LABEL);
1✔
749
        serialize(out, GraphStoreConfiguration.ENABLE_ELEMENT_TIME_SET);
1✔
750
        // Was GraphStoreConfiguration.ENABLE_NODE_PROPERTIES
751
        serialize(out, true);
1✔
752
        // Was GraphStoreConfiguration.ENABLE_EDGE_PROPERTIES
753
        serialize(out, true);
1✔
754
    }
1✔
755

756
    private GraphStoreConfigurationVersion deserializeGraphStoreConfiguration(final DataInput is) throws IOException, ClassNotFoundException {
757
        boolean enableElementLabel = (Boolean) deserialize(is);
1✔
758
        boolean enableElementTimestamp = (Boolean) deserialize(is);
1✔
759
        boolean enableNodeProperties = (Boolean) deserialize(is);
1✔
760
        boolean enableEdgeProperties = (Boolean) deserialize(is);
1✔
761

762
        graphStoreConfigurationVersion = new GraphStoreConfigurationVersion(enableElementLabel, enableElementTimestamp,
1✔
763
                enableNodeProperties, enableEdgeProperties);
764
        return graphStoreConfigurationVersion;
1✔
765
    }
766

767
    private void serializeGraphVersion(final DataOutput out, final GraphVersion graphVersion) throws IOException {
768
        serialize(out, graphVersion.nodeVersion);
1✔
769
        serialize(out, graphVersion.edgeVersion);
1✔
770
    }
1✔
771

772
    private GraphVersion deserializeGraphVersion(final DataInput is) throws IOException, ClassNotFoundException {
773
        GraphVersion graphVersion = new GraphVersion(null);
1✔
774

775
        int nodeVersion = (Integer) deserialize(is);
1✔
776
        int edgeVersion = (Integer) deserialize(is);
1✔
777

778
        graphVersion.nodeVersion = nodeVersion;
1✔
779
        graphVersion.edgeVersion = edgeVersion;
1✔
780

781
        return graphVersion;
1✔
782
    }
783

784
    private void serializeNodeProperties(final DataOutput out, final NodePropertiesImpl nodeProperties) throws IOException {
785
        serialize(out, nodeProperties.x);
1✔
786
        serialize(out, nodeProperties.y);
1✔
787
        serialize(out, nodeProperties.z);
1✔
788
        serialize(out, nodeProperties.rgba);
1✔
789
        serialize(out, nodeProperties.size);
1✔
790
        serialize(out, nodeProperties.fixed);
1✔
791
        serialize(out, nodeProperties.textProperties);
1✔
792
    }
1✔
793

794
    private NodePropertiesImpl deserializeNodeProperties(final DataInput is) throws IOException, ClassNotFoundException {
795
        float x = (Float) deserialize(is);
1✔
796
        float y = (Float) deserialize(is);
1✔
797
        float z = (Float) deserialize(is);
1✔
798
        int rgba = (Integer) deserialize(is);
1✔
799
        float size = (Float) deserialize(is);
1✔
800
        boolean fixed = (Boolean) deserialize(is);
1✔
801
        TextPropertiesImpl textProperties = (TextPropertiesImpl) deserialize(is);
1✔
802

803
        NodePropertiesImpl props = new NodePropertiesImpl();
1✔
804
        props.x = x;
1✔
805
        props.y = y;
1✔
806
        props.z = z;
1✔
807
        props.rgba = rgba;
1✔
808
        props.size = size;
1✔
809
        props.fixed = fixed;
1✔
810
        props.setTextProperties(textProperties);
1✔
811

812
        return props;
1✔
813
    }
814

815
    private void serializeEdgeProperties(final DataOutput out, final EdgePropertiesImpl edgeProperties) throws IOException {
816
        serialize(out, edgeProperties.rgba);
1✔
817
        serialize(out, edgeProperties.textProperties);
1✔
818
    }
1✔
819

820
    private EdgePropertiesImpl deserializeEdgeProperties(final DataInput is) throws IOException, ClassNotFoundException {
821
        int rgba = (Integer) deserialize(is);
1✔
822
        TextPropertiesImpl textProperties = (TextPropertiesImpl) deserialize(is);
1✔
823

824
        EdgePropertiesImpl props = new EdgePropertiesImpl();
1✔
825
        props.rgba = rgba;
1✔
826
        props.setTextProperties(textProperties);
1✔
827

828
        // Gephi versions before 0.11 used zero alpha to indicate that the element has
829
        // no color
830
        // Override this to avoid hidden elements
831
        if (props.alpha() <= 0f) {
1✔
832
            props.setAlpha(1f);
×
833
        }
834

835
        return props;
1✔
836
    }
837

838
    private void serializeTextProperties(final DataOutput out, final TextPropertiesImpl textProperties) throws IOException {
839
        serialize(out, textProperties.size);
1✔
840
        serialize(out, textProperties.rgba);
1✔
841
        serialize(out, textProperties.visible);
1✔
842
        serialize(out, textProperties.text);
1✔
843
        serialize(out, textProperties.width);
1✔
844
        serialize(out, textProperties.height);
1✔
845
    }
1✔
846

847
    private TextPropertiesImpl deserializeTextProperties(final DataInput is) throws IOException, ClassNotFoundException {
848
        float size = (Float) deserialize(is);
1✔
849
        int rgba = (Integer) deserialize(is);
1✔
850
        boolean visible = (Boolean) deserialize(is);
1✔
851
        String text = (String) deserialize(is);
1✔
852
        float width = (Float) deserialize(is);
1✔
853
        float height = (Float) deserialize(is);
1✔
854

855
        TextPropertiesImpl props = new TextPropertiesImpl();
1✔
856
        props.size = size;
1✔
857
        props.rgba = rgba;
1✔
858
        props.visible = visible;
1✔
859
        props.text = text;
1✔
860
        props.width = width;
1✔
861
        props.height = height;
1✔
862

863
        // Gephi versions before 0.11 used zero alpha to indicate that the element has
864
        // no color
865
        // Override this to avoid hidden elements
866
        if (props.getAlpha() <= 0f) {
1✔
867
            props.setAlpha(1f);
×
868
        }
869

870
        return props;
1✔
871
    }
872

873
    private void serializeTimestampSet(final DataOutput out, final TimestampSet timestampSet) throws IOException {
874
        serialize(out, timestampSet.toPrimitiveArray());
1✔
875
    }
1✔
876

877
    private TimestampSet deserializeTimestampSet(DataInput is) throws IOException, ClassNotFoundException {
878
        double[] r = (double[]) deserialize(is);
1✔
879

880
        return new TimestampSet(r);
1✔
881
    }
882

883
    private void serializeIntervalSet(final DataOutput out, final IntervalSet intervalSet) throws IOException {
884
        serialize(out, intervalSet.getIntervals());
1✔
885
    }
1✔
886

887
    private IntervalSet deserializeIntervalSet(DataInput is) throws IOException, ClassNotFoundException {
888
        double[] r = (double[]) deserialize(is);
1✔
889

890
        return new IntervalSet(r);
1✔
891
    }
892

893
    private void serializeTimestampMap(final DataOutput out, final TimestampMap timestampMap) throws IOException {
894
        serialize(out, timestampMap.getTimestamps());
1✔
895
        Class mapClass = timestampMap.getClass();
1✔
896
        if (mapClass.equals(TimestampBooleanMap.class)) {
1✔
897
            serialize(out, ((TimestampBooleanMap) timestampMap).toBooleanArray());
1✔
898
        } else if (mapClass.equals(TimestampByteMap.class)) {
1✔
899
            serialize(out, ((TimestampByteMap) timestampMap).toByteArray());
1✔
900
        } else if (mapClass.equals(TimestampCharMap.class)) {
1✔
901
            serialize(out, ((TimestampCharMap) timestampMap).toCharacterArray());
1✔
902
        } else if (mapClass.equals(TimestampDoubleMap.class)) {
1✔
903
            serialize(out, ((TimestampDoubleMap) timestampMap).toDoubleArray());
1✔
904
        } else if (mapClass.equals(TimestampFloatMap.class)) {
1✔
905
            serialize(out, ((TimestampFloatMap) timestampMap).toFloatArray());
1✔
906
        } else if (mapClass.equals(TimestampIntegerMap.class)) {
1✔
907
            serialize(out, ((TimestampIntegerMap) timestampMap).toIntegerArray());
1✔
908
        } else if (mapClass.equals(TimestampLongMap.class)) {
1✔
909
            serialize(out, ((TimestampLongMap) timestampMap).toLongArray());
1✔
910
        } else if (mapClass.equals(TimestampShortMap.class)) {
1✔
911
            serialize(out, ((TimestampShortMap) timestampMap).toShortArray());
1✔
912
        } else if (mapClass.equals(TimestampStringMap.class)) {
1✔
913
            serialize(out, timestampMap.toValuesArray());
1✔
914
        } else {
915
            throw new RuntimeException("Unrecognized timestamp map class");
×
916
        }
917
    }
1✔
918

919
    private TimestampMap deserializeTimestampMap(final DataInput is) throws IOException, ClassNotFoundException {
920
        double[] timeStamps = (double[]) deserialize(is);
1✔
921
        Object values = deserialize(is);
1✔
922

923
        Class mapClass = values.getClass();
1✔
924
        TimestampMap valueSet;
925
        if (mapClass.equals(boolean[].class)) {
1✔
926
            valueSet = new TimestampBooleanMap(timeStamps, (boolean[]) values);
1✔
927
        } else if (mapClass.equals(byte[].class)) {
1✔
928
            valueSet = new TimestampByteMap(timeStamps, (byte[]) values);
1✔
929
        } else if (mapClass.equals(char[].class)) {
1✔
930
            valueSet = new TimestampCharMap(timeStamps, (char[]) values);
1✔
931
        } else if (mapClass.equals(double[].class)) {
1✔
932
            valueSet = new TimestampDoubleMap(timeStamps, (double[]) values);
1✔
933
        } else if (mapClass.equals(float[].class)) {
1✔
934
            valueSet = new TimestampFloatMap(timeStamps, (float[]) values);
1✔
935
        } else if (mapClass.equals(int[].class)) {
1✔
936
            valueSet = new TimestampIntegerMap(timeStamps, (int[]) values);
1✔
937
        } else if (mapClass.equals(long[].class)) {
1✔
938
            valueSet = new TimestampLongMap(timeStamps, (long[]) values);
1✔
939
        } else if (mapClass.equals(short[].class)) {
1✔
940
            valueSet = new TimestampShortMap(timeStamps, (short[]) values);
1✔
941
        } else if (mapClass.equals(String[].class)) {
1✔
942
            valueSet = new TimestampStringMap(timeStamps, (String[]) values);
1✔
943
        } else {
944
            throw new RuntimeException("Unrecognized timestamp map class");
×
945
        }
946
        return valueSet;
1✔
947
    }
948

949
    private void serializeIntervalMap(final DataOutput out, final IntervalMap intervalMap) throws IOException {
950
        serialize(out, intervalMap.getIntervals());
1✔
951
        Class mapClass = intervalMap.getClass();
1✔
952
        if (mapClass.equals(IntervalBooleanMap.class)) {
1✔
953
            serialize(out, ((IntervalBooleanMap) intervalMap).toBooleanArray());
1✔
954
        } else if (mapClass.equals(IntervalByteMap.class)) {
1✔
955
            serialize(out, ((IntervalByteMap) intervalMap).toByteArray());
1✔
956
        } else if (mapClass.equals(IntervalCharMap.class)) {
1✔
957
            serialize(out, ((IntervalCharMap) intervalMap).toCharacterArray());
1✔
958
        } else if (mapClass.equals(IntervalDoubleMap.class)) {
1✔
959
            serialize(out, ((IntervalDoubleMap) intervalMap).toDoubleArray());
1✔
960
        } else if (mapClass.equals(IntervalFloatMap.class)) {
1✔
961
            serialize(out, ((IntervalFloatMap) intervalMap).toFloatArray());
1✔
962
        } else if (mapClass.equals(IntervalIntegerMap.class)) {
1✔
963
            serialize(out, ((IntervalIntegerMap) intervalMap).toIntegerArray());
1✔
964
        } else if (mapClass.equals(IntervalLongMap.class)) {
1✔
965
            serialize(out, ((IntervalLongMap) intervalMap).toLongArray());
1✔
966
        } else if (mapClass.equals(IntervalShortMap.class)) {
1✔
967
            serialize(out, ((IntervalShortMap) intervalMap).toShortArray());
1✔
968
        } else if (mapClass.equals(IntervalStringMap.class)) {
1✔
969
            serialize(out, intervalMap.toValuesArray());
1✔
970
        } else {
971
            throw new RuntimeException("Unrecognized interval map class");
×
972
        }
973
    }
1✔
974

975
    private IntervalMap deserializeIntervalMap(final DataInput is) throws IOException, ClassNotFoundException {
976
        double[] intervals = (double[]) deserialize(is);
1✔
977
        Object values = deserialize(is);
1✔
978

979
        Class mapClass = values.getClass();
1✔
980
        IntervalMap valueSet;
981
        if (mapClass.equals(boolean[].class)) {
1✔
982
            valueSet = new IntervalBooleanMap(intervals, (boolean[]) values);
1✔
983
        } else if (mapClass.equals(byte[].class)) {
1✔
984
            valueSet = new IntervalByteMap(intervals, (byte[]) values);
1✔
985
        } else if (mapClass.equals(char[].class)) {
1✔
986
            valueSet = new IntervalCharMap(intervals, (char[]) values);
1✔
987
        } else if (mapClass.equals(double[].class)) {
1✔
988
            valueSet = new IntervalDoubleMap(intervals, (double[]) values);
1✔
989
        } else if (mapClass.equals(float[].class)) {
1✔
990
            valueSet = new IntervalFloatMap(intervals, (float[]) values);
1✔
991
        } else if (mapClass.equals(int[].class)) {
1✔
992
            valueSet = new IntervalIntegerMap(intervals, (int[]) values);
1✔
993
        } else if (mapClass.equals(long[].class)) {
1✔
994
            valueSet = new IntervalLongMap(intervals, (long[]) values);
1✔
995
        } else if (mapClass.equals(short[].class)) {
1✔
996
            valueSet = new IntervalShortMap(intervals, (short[]) values);
1✔
997
        } else if (mapClass.equals(String[].class)) {
1✔
998
            valueSet = new IntervalStringMap(intervals, (String[]) values);
1✔
999
        } else {
1000
            throw new RuntimeException("Unrecognized interval map class");
×
1001
        }
1002
        return valueSet;
1✔
1003
    }
1004

1005
    private void serializeTimestampIndexStore(final DataOutput out, final TimestampIndexStore timestampIndexStore) throws IOException {
1006
        serialize(out, timestampIndexStore.elementType);
1✔
1007

1008
        // The time index is derived state: inserting the nodes and edges rebuilds it. These fields are written empty to
1009
        // keep the block layout, which earlier versions read positionally.
1010
        serialize(out, 0);
1✔
1011
        serialize(out, new double[0]);
1✔
1012
        serialize(out, new int[0]);
1✔
1013
        serialize(out, new int[0]);
1✔
1014
        serialize(out, new int[0]);
1✔
1015
    }
1✔
1016

1017
    private TimestampIndexStore deserializeTimestampIndexStore(final DataInput is) throws IOException, ClassNotFoundException {
1018
        TimestampIndexStore timestampIndexStore;
1019

1020
        Class cls = (Class) deserialize(is);
1✔
1021
        if (cls.equals(Node.class)) {
1✔
1022
            timestampIndexStore = (TimestampIndexStore) model.store.timeStore.nodeIndexStore;
1✔
1023
        } else {
1024
            timestampIndexStore = (TimestampIndexStore) model.store.timeStore.edgeIndexStore;
1✔
1025
        }
1026

1027
        // The time index is derived state: inserting the nodes and edges rebuilds it. These fields are read to advance
1028
        // the stream and discarded. The casts check each field's type. See serializeTimestampIndexStore for the layout.
1029
        int length = (Integer) deserialize(is);
1✔
1030
        double[] timestamps = (double[]) deserialize(is);
1✔
1031
        int[] timeIndices = (int[]) deserialize(is);
1✔
1032
        int[] garbage = (int[]) deserialize(is);
1✔
1033
        int[] counts = (int[]) deserialize(is);
1✔
1034

1035
        return timestampIndexStore;
1✔
1036
    }
1037

1038
    private void serializeIntervalIndexStore(final DataOutput out, final IntervalIndexStore intervalIndexStore) throws IOException {
1039
        serialize(out, intervalIndexStore.elementType);
1✔
1040

1041
        // The time index is derived state: inserting the nodes and edges rebuilds it. These fields are written empty to
1042
        // keep the block layout, which earlier versions read positionally. The map is written with a zero entry count.
1043
        serialize(out, 0);
1✔
1044
        serialize(out, 0);
1✔
1045
        serialize(out, new int[0]);
1✔
1046
        serialize(out, new int[0]);
1✔
1047
    }
1✔
1048

1049
    private IntervalIndexStore deserializeIntervalIndexStore(final DataInput is) throws IOException, ClassNotFoundException {
1050
        IntervalIndexStore intervalIndexStore;
1051

1052
        Class cls = (Class) deserialize(is);
1✔
1053
        if (cls.equals(Node.class)) {
1✔
1054
            intervalIndexStore = (IntervalIndexStore) model.store.timeStore.nodeIndexStore;
1✔
1055
        } else {
1056
            intervalIndexStore = (IntervalIndexStore) model.store.timeStore.edgeIndexStore;
1✔
1057
        }
1058

1059
        // The time index is derived state: inserting the nodes and edges rebuilds it. These fields are read to advance
1060
        // the stream and discarded. The casts check each field's type. See serializeIntervalIndexStore for the layout.
1061
        int length = (Integer) deserialize(is);
1✔
1062
        int mapSize = (Integer) deserialize(is);
1✔
1063
        for (int i = 0; i < mapSize; i++) {
1✔
1064
            Interval interval = (Interval) deserialize(is);
×
1065
            Integer timeIndex = (Integer) deserialize(is);
×
1066
        }
1067
        int[] garbage = (int[]) deserialize(is);
1✔
1068
        int[] counts = (int[]) deserialize(is);
1✔
1069

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:
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