Skip to content

Commit 613996f

Browse files
authored
Merge pull request #4754 from ntisseyre/management_api
Schema Management APIs for Enhanced Debugging in JanusGraph
2 parents 53a5332 + 167758d commit 613996f

File tree

7 files changed

+175
-0
lines changed

7 files changed

+175
-0
lines changed

janusgraph-backend-testutils/src/main/java/org/janusgraph/graphdb/JanusGraphCustomIdTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import com.google.common.base.Preconditions;
1818
import io.github.artsok.RepeatedIfExceptionsTest;
19+
import org.apache.commons.codec.DecoderException;
1920
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
2021
import org.apache.tinkerpop.gremlin.structure.Direction;
2122
import org.apache.tinkerpop.gremlin.structure.T;
@@ -582,6 +583,38 @@ public void testWriteAndReadWithJanusGraphIoRegistryWithGraphson(@TempDir Path t
582583
testWritingAndReading(file.toFile());
583584
}
584585

586+
@Test
587+
public void testGetVertexId() throws DecoderException {
588+
589+
open(true, true);
590+
591+
mgmt.makeVertexLabel("cat").make();
592+
makeKey("id", Integer.class);
593+
makeKey("name", String.class);
594+
595+
mgmt.commit();
596+
597+
Vertex v1 = tx.addVertex(T.id, 1000L, T.label, "cat");
598+
v1.property("id", 1);
599+
v1.property("name", "cat_1");
600+
Object vertexId1 = v1.id();
601+
602+
Vertex v2 = tx.addVertex(T.id, "id_cat2", T.label, "cat");
603+
v2.property("id", 2);
604+
v2.property("name", "cat_2");
605+
Object vertexId2 = v2.id();
606+
607+
tx.commit();
608+
609+
mgmt = graph.openManagement();
610+
611+
String hex1 = mgmt.getVertexKey(vertexId1);
612+
String hex2 = mgmt.getVertexKey(vertexId2);
613+
614+
assertEquals(vertexId1, mgmt.getVertexId(hex1));
615+
assertEquals(vertexId2, mgmt.getVertexId(hex2));
616+
}
617+
585618
private void testWritingAndReading(File f) {
586619
GraphTraversalSource g = graph.traversal();
587620
Vertex fromV = g.addV().property("name", f.getName()).property(T.id, "custom_id").next();

janusgraph-backend-testutils/src/main/java/org/janusgraph/graphdb/JanusGraphIndexTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.common.collect.Iterators;
2020
import com.google.common.collect.Sets;
2121
import io.github.artsok.RepeatedIfExceptionsTest;
22+
import org.apache.commons.codec.DecoderException;
2223
import org.apache.tinkerpop.gremlin.process.traversal.P;
2324
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
2425
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
@@ -96,6 +97,8 @@
9697
import org.janusgraph.graphdb.tinkerpop.optimize.step.JanusGraphStep;
9798
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphMixedIndexCountStrategy;
9899
import org.janusgraph.graphdb.transaction.StandardJanusGraphTx;
100+
import org.janusgraph.graphdb.types.CompositeIndexType;
101+
import org.janusgraph.graphdb.types.IndexField;
99102
import org.janusgraph.graphdb.types.MixedIndexType;
100103
import org.janusgraph.graphdb.types.ParameterType;
101104
import org.janusgraph.graphdb.types.StandardEdgeLabelMaker;
@@ -4346,4 +4349,37 @@ public void testMixedIndexAggregatedCountReturnsCorrectResult() {
43464349
);
43474350
}
43484351
}
4352+
4353+
@Test
4354+
public void testGetIndexInfo() throws DecoderException {
4355+
4356+
clopen();
4357+
4358+
mgmt.makeVertexLabel("cat").make();
4359+
4360+
makeKey("id", Integer.class);
4361+
final PropertyKey nameKey = makeKey("name", String.class);
4362+
4363+
String indexName = "searchByName";
4364+
mgmt.buildIndex(indexName, Vertex.class)
4365+
.addKey(nameKey)
4366+
.buildCompositeIndex();
4367+
mgmt.commit();
4368+
4369+
mgmt = graph.openManagement();
4370+
4371+
Map<String, Object> fieldValues = new HashMap<>();
4372+
fieldValues.put("name", "someName");
4373+
4374+
String hexString = mgmt.getIndexKey(indexName, fieldValues);
4375+
CompositeIndexType indexType = mgmt.getIndexInfo(hexString);
4376+
4377+
IndexField[] indexFields = new IndexField[1];
4378+
indexFields[0] = IndexField.of(nameKey);
4379+
4380+
assertEquals(indexName, indexType.getName());
4381+
assertEquals(1, indexType.getFieldKeys().length);
4382+
assertEquals(nameKey, indexType.getFieldKeys()[0].getFieldKey());
4383+
assertEquals(0, indexType.getInlineFieldKeys().length);
4384+
}
43494385
}

janusgraph-core/src/main/java/org/janusgraph/core/schema/JanusGraphManagement.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package org.janusgraph.core.schema;
1616

17+
import org.apache.commons.codec.DecoderException;
1718
import org.apache.tinkerpop.gremlin.process.traversal.Order;
1819
import org.apache.tinkerpop.gremlin.structure.Direction;
1920
import org.apache.tinkerpop.gremlin.structure.Element;
@@ -23,9 +24,11 @@
2324
import org.janusgraph.core.RelationType;
2425
import org.janusgraph.core.VertexLabel;
2526
import org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture;
27+
import org.janusgraph.graphdb.types.CompositeIndexType;
2628

2729
import java.time.Duration;
2830
import java.util.List;
31+
import java.util.Map;
2932
import java.util.Set;
3033

3134
/**
@@ -469,4 +472,33 @@ interface IndexBuilder {
469472
*/
470473
String printIndexes();
471474

475+
/**
476+
* Get vertexId for the given hex string
477+
* @param hexString
478+
* @return vertex Id
479+
* @throws DecoderException
480+
*/
481+
Object getVertexId(String hexString) throws DecoderException;
482+
483+
/**
484+
* Get a hex string representing vertex id
485+
* @param vertexId vertex id
486+
* @return a hex string representing bytes of vertex id
487+
*/
488+
String getVertexKey(Object vertexId);
489+
490+
/**
491+
* Get a hex string representing index key
492+
* @param indexName schema index name
493+
* @param fieldValues index fields with values
494+
* @return a hex string representing bytes of index key
495+
*/
496+
String getIndexKey(String indexName, Map<String, Object> fieldValues);
497+
498+
/**
499+
* Get index info from given hex string
500+
* @param hexString
501+
* @return composite index info
502+
*/
503+
CompositeIndexType getIndexInfo(String hexString) throws DecoderException;
472504
}

janusgraph-core/src/main/java/org/janusgraph/graphdb/database/IndexSerializer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,10 @@ public long getIndexIdFromKey(StaticBuffer key) {
525525
return IndexRecordUtil.getIndexIdFromKey(key, hashKeys, hashLength);
526526
}
527527

528+
public StaticBuffer getIndexKey(CompositeIndexType index, Map<String, Object> fieldValues) {
529+
return IndexRecordUtil.getIndexKey(index, fieldValues, serializer, hashKeys, hashLength);
530+
}
531+
528532
public boolean isHashKeys() {
529533
return hashKeys;
530534
}

janusgraph-core/src/main/java/org/janusgraph/graphdb/database/management/ManagementSystem.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
import com.google.common.base.Preconditions;
1818
import com.google.common.collect.Iterables;
19+
import org.apache.commons.codec.DecoderException;
20+
import org.apache.commons.codec.binary.Hex;
1921
import org.apache.commons.lang3.StringUtils;
2022
import org.apache.tinkerpop.gremlin.structure.Direction;
2123
import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -51,6 +53,7 @@
5153
import org.janusgraph.core.schema.SchemaStatus;
5254
import org.janusgraph.core.schema.VertexLabelMaker;
5355
import org.janusgraph.diskstorage.BackendException;
56+
import org.janusgraph.diskstorage.StaticBuffer;
5457
import org.janusgraph.diskstorage.configuration.BasicConfiguration;
5558
import org.janusgraph.diskstorage.configuration.ConfigOption;
5659
import org.janusgraph.diskstorage.configuration.ModifiableConfiguration;
@@ -62,6 +65,7 @@
6265
import org.janusgraph.diskstorage.keycolumnvalue.scan.ScanMetrics;
6366
import org.janusgraph.diskstorage.keycolumnvalue.scan.StandardScanner;
6467
import org.janusgraph.diskstorage.log.Log;
68+
import org.janusgraph.diskstorage.util.StaticArrayBuffer;
6569
import org.janusgraph.graphdb.database.IndexSerializer;
6670
import org.janusgraph.graphdb.database.StandardJanusGraph;
6771
import org.janusgraph.graphdb.database.cache.SchemaCache;
@@ -545,6 +549,28 @@ public String printIndexes() {
545549
return this.printIndexes(true);
546550
}
547551

552+
@Override
553+
public Object getVertexId(String hexString) throws DecoderException {
554+
return this.graph.getIDManager().getKeyID(StaticArrayBuffer.of(Hex.decodeHex(hexString)));
555+
}
556+
557+
@Override
558+
public String getVertexKey(Object vertexId) {
559+
return Hex.encodeHexString(graph.getIDManager().getKey(vertexId).asByteBuffer());
560+
}
561+
562+
@Override
563+
public String getIndexKey(String indexName, Map<String, Object> fieldValues) {
564+
StaticBuffer staticBuffer = transaction.getCompositeIndexKey(indexName, fieldValues);
565+
return Hex.encodeHexString(staticBuffer.asByteBuffer());
566+
}
567+
568+
@Override
569+
public CompositeIndexType getIndexInfo(String hexString) throws DecoderException {
570+
StaticArrayBuffer indexKey = StaticArrayBuffer.of(Hex.decodeHex(hexString));
571+
return transaction.getCompositeIndexInfo(indexKey);
572+
}
573+
548574
private String printIndexes(boolean calledDirectly) {
549575
StringBuilder sb = new StringBuilder();
550576
String pattern = "%-30s | %-11s | %-9s | %-14s | %-10s %10s |%n";

janusgraph-core/src/main/java/org/janusgraph/graphdb/database/util/IndexRecordUtil.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import java.util.Iterator;
7474
import java.util.List;
7575
import java.util.Map;
76+
import java.util.NoSuchElementException;
7677

7778
import static org.janusgraph.util.encoding.LongEncoding.STRING_ENCODING_MARKER;
7879

@@ -331,6 +332,19 @@ public static StaticBuffer getIndexKey(CompositeIndexType index, IndexRecordEntr
331332
return getIndexKey(index, IndexRecordUtil.getValues(record), serializer, hashKeys, hashLength);
332333
}
333334

335+
public static StaticBuffer getIndexKey(CompositeIndexType index, Map<String, Object> fieldValues, Serializer serializer, boolean hashKeys, HashingUtil.HashLength hashLength) {
336+
Object[] values = Arrays.stream(index.getFieldKeys()).map(field -> {
337+
String fieldName = field.getFieldKey().name();
338+
if (fieldValues.containsKey(fieldName)) {
339+
return fieldValues.get(fieldName);
340+
} else {
341+
throw new NoSuchElementException("Value for fieldName=" + fieldName + " is not provided for indexName=" + index.getName());
342+
}
343+
}).toArray();
344+
345+
return getIndexKey(index, values, serializer, hashKeys, hashLength);
346+
}
347+
334348
public static StaticBuffer getIndexKey(CompositeIndexType index, Object[] values, Serializer serializer, boolean hashKeys, HashingUtil.HashLength hashLength) {
335349
final DataOutput out = serializer.getDataOutput(8*DEFAULT_OBJECT_BYTELEN + 8);
336350
VariableLong.writePositive(out, index.longId());

janusgraph-core/src/main/java/org/janusgraph/graphdb/transaction/StandardJanusGraphTx.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
import org.janusgraph.diskstorage.BackendException;
5050
import org.janusgraph.diskstorage.BackendTransaction;
5151
import org.janusgraph.diskstorage.EntryList;
52+
import org.janusgraph.diskstorage.StaticBuffer;
5253
import org.janusgraph.diskstorage.indexing.IndexTransaction;
5354
import org.janusgraph.diskstorage.keycolumnvalue.MultiKeysQueryGroups;
5455
import org.janusgraph.diskstorage.keycolumnvalue.SliceQuery;
56+
import org.janusgraph.diskstorage.util.StaticArrayBuffer;
5557
import org.janusgraph.diskstorage.util.time.TimestampProvider;
5658
import org.janusgraph.graphdb.database.EdgeSerializer;
5759
import org.janusgraph.graphdb.database.IndexSerializer;
@@ -1243,6 +1245,34 @@ public VertexLabel getOrCreateVertexLabel(String name) {
12431245
return vertexLabel;
12441246
}
12451247

1248+
public StaticBuffer getCompositeIndexKey(String indexName, Map<String, Object> fieldValues) {
1249+
JanusGraphSchemaVertex schemaVertex = getSchemaVertex(JanusGraphSchemaCategory.GRAPHINDEX.getSchemaName(indexName));
1250+
Preconditions.checkNotNull(schemaVertex, "Index with name [" + indexName + "] was not found");
1251+
IndexType indexType = schemaVertex.asIndexType();
1252+
if (indexType instanceof CompositeIndexType) {
1253+
CompositeIndexType compositeIndex = (CompositeIndexType) indexType;
1254+
StaticBuffer indexKey = indexSerializer.getIndexKey(compositeIndex, fieldValues);
1255+
return indexKey;
1256+
} else {
1257+
throw new IllegalArgumentException("Index with name [" + indexName + "] is not a composite index");
1258+
}
1259+
}
1260+
1261+
public CompositeIndexType getCompositeIndexInfo(StaticArrayBuffer indexKey) {
1262+
long schemaVertexId = indexSerializer.getIndexIdFromKey(indexKey);
1263+
InternalVertex typeVertex = vertexCache.get(schemaVertexId, existingVertexRetriever);
1264+
1265+
Preconditions.checkNotNull(typeVertex, "Index with key [" + indexKey + "] was not found");
1266+
JanusGraphSchemaVertex schemaVertex = (JanusGraphSchemaVertex) typeVertex;
1267+
1268+
IndexType indexType = schemaVertex.asIndexType();
1269+
if (indexType instanceof CompositeIndexType) {
1270+
return (CompositeIndexType) indexType;
1271+
} else {
1272+
throw new IllegalArgumentException("Index with key [" + indexKey + "] is not a composite index");
1273+
}
1274+
}
1275+
12461276
@Override
12471277
public VertexLabelMaker makeVertexLabel(String name) {
12481278
StandardVertexLabelMaker maker = new StandardVertexLabelMaker(this);

0 commit comments

Comments
 (0)