Skip to content

Commit

Permalink
Merge pull request #4755 from ntisseyre/management_api
Browse files Browse the repository at this point in the history
Returning Composite index structure and field values for hex string
  • Loading branch information
ntisseyre authored Jan 26, 2025
2 parents 613996f + 2db56c9 commit 46a971a
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.janusgraph.core.attribute.Geoshape;
import org.janusgraph.core.attribute.Text;
import org.janusgraph.core.log.TransactionRecovery;
import org.janusgraph.core.schema.CompositeIndexInfo;
import org.janusgraph.core.schema.JanusGraphIndex;
import org.janusgraph.core.schema.JanusGraphManagement;
import org.janusgraph.core.schema.Mapping;
Expand Down Expand Up @@ -97,7 +98,6 @@
import org.janusgraph.graphdb.tinkerpop.optimize.step.JanusGraphStep;
import org.janusgraph.graphdb.tinkerpop.optimize.strategy.JanusGraphMixedIndexCountStrategy;
import org.janusgraph.graphdb.transaction.StandardJanusGraphTx;
import org.janusgraph.graphdb.types.CompositeIndexType;
import org.janusgraph.graphdb.types.IndexField;
import org.janusgraph.graphdb.types.MixedIndexType;
import org.janusgraph.graphdb.types.ParameterType;
Expand Down Expand Up @@ -162,7 +162,6 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;


/**
* @author Matthias Broecheler ([email protected])
*/
Expand Down Expand Up @@ -4357,29 +4356,82 @@ public void testGetIndexInfo() throws DecoderException {

mgmt.makeVertexLabel("cat").make();

makeKey("id", Integer.class);
final PropertyKey idKey = makeKey("id", Integer.class);
final PropertyKey nameKey = makeKey("name", String.class);
final PropertyKey metaKey = makeKey("meta", Object.class);

String searchByNameIndex = "searchByName";
mgmt.buildIndex(searchByNameIndex, Vertex.class)
.addKey(nameKey)
.buildCompositeIndex();

String indexName = "searchByName";
mgmt.buildIndex(indexName, Vertex.class)
String searchByMetaIndex = "searchByMeta";
mgmt.buildIndex(searchByMetaIndex, Vertex.class)
.addKey(nameKey)
.addKey(metaKey)
.buildCompositeIndex();

String inlinePropIndex = "inlineProp";
mgmt.buildIndex(inlinePropIndex, Vertex.class)
.addKey(nameKey)
.addKey(metaKey)
.addInlinePropertyKey(idKey)
.buildCompositeIndex();

mgmt.commit();

mgmt = graph.openManagement();

//Read index with single property
Map<String, Object> fieldValues = new HashMap<>();
fieldValues.put("name", "someName");

String hexString = mgmt.getIndexKey(indexName, fieldValues);
CompositeIndexType indexType = mgmt.getIndexInfo(hexString);
String hexString = mgmt.getIndexKey(searchByNameIndex, fieldValues);
CompositeIndexInfo indexInfo = mgmt.getIndexInfo(hexString);

IndexField[] indexFields = new IndexField[1];
indexFields[0] = IndexField.of(nameKey);

assertEquals(indexName, indexType.getName());
assertEquals(1, indexType.getFieldKeys().length);
assertEquals(nameKey, indexType.getFieldKeys()[0].getFieldKey());
assertEquals(0, indexType.getInlineFieldKeys().length);
assertEquals(searchByNameIndex, indexInfo.getIndexName());
assertEquals(1, indexInfo.getCompositeIndexType().getFieldKeys().length);
assertEquals("someName", indexInfo.getValues().get(nameKey));
assertEquals(0, indexInfo.getCompositeIndexType().getInlineFieldKeys().length);

//Read index with multi properties
fieldValues = new HashMap<>();
fieldValues.put("name", "name1");
fieldValues.put("meta", "hello");

hexString = mgmt.getIndexKey(searchByMetaIndex, fieldValues);
indexInfo = mgmt.getIndexInfo(hexString);

indexFields = new IndexField[2];
indexFields[0] = IndexField.of(nameKey);
indexFields[1] = IndexField.of(metaKey);

assertEquals(searchByMetaIndex, indexInfo.getIndexName());
assertEquals(2, indexInfo.getCompositeIndexType().getFieldKeys().length);
assertEquals("name1", indexInfo.getValues().get(nameKey));
assertEquals("hello", indexInfo.getValues().get(metaKey));
assertEquals(0, indexInfo.getCompositeIndexType().getInlineFieldKeys().length);

//Read index with inline properties
fieldValues = new HashMap<>();
fieldValues.put("name", "name2");
fieldValues.put("meta", "bye");

hexString = mgmt.getIndexKey(inlinePropIndex, fieldValues);
indexInfo = mgmt.getIndexInfo(hexString);

indexFields = new IndexField[2];
indexFields[0] = IndexField.of(nameKey);
indexFields[1] = IndexField.of(metaKey);

assertEquals(inlinePropIndex, indexInfo.getIndexName());
assertEquals(2, indexInfo.getCompositeIndexType().getFieldKeys().length);
assertEquals("name2", indexInfo.getValues().get(nameKey));
assertEquals("bye", indexInfo.getValues().get(metaKey));
assertEquals(1, indexInfo.getCompositeIndexType().getInlineFieldKeys().length);
assertEquals("id", indexInfo.getCompositeIndexType().getInlineFieldKeys()[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2025 JanusGraph Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.janusgraph.core.schema;

import org.janusgraph.core.PropertyKey;
import org.janusgraph.graphdb.types.CompositeIndexType;

import java.util.HashMap;
import java.util.Map;

public class CompositeIndexInfo {
final CompositeIndexType compositeIndexType;
final Object[] indexFieldValues;

final Map<PropertyKey, Object> indexValues;

public CompositeIndexInfo(CompositeIndexType compositeIndexType, Object[] indexFieldValues) {
this.compositeIndexType = compositeIndexType;
this.indexFieldValues = indexFieldValues;

this.indexValues = new HashMap<>();
for (int i = 0; i < compositeIndexType.getFieldKeys().length; i++) {
PropertyKey p = compositeIndexType.getFieldKeys()[i].getFieldKey();
Object v = indexFieldValues[i];
this.indexValues.put(p, v);
}
}

public CompositeIndexType getCompositeIndexType() {
return compositeIndexType;
}

public String getIndexName() {
return compositeIndexType.getName();
}

public Map<PropertyKey, Object> getValues() {
return indexValues;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.janusgraph.core.RelationType;
import org.janusgraph.core.VertexLabel;
import org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture;
import org.janusgraph.graphdb.types.CompositeIndexType;

import java.time.Duration;
import java.util.List;
Expand Down Expand Up @@ -500,5 +499,5 @@ interface IndexBuilder {
* @param hexString
* @return composite index info
*/
CompositeIndexType getIndexInfo(String hexString) throws DecoderException;
CompositeIndexInfo getIndexInfo(String hexString) throws DecoderException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.SchemaViolationException;
import org.janusgraph.core.attribute.Geoshape;
import org.janusgraph.core.schema.CompositeIndexInfo;
import org.janusgraph.core.schema.Parameter;
import org.janusgraph.core.schema.SchemaStatus;
import org.janusgraph.diskstorage.BackendException;
Expand Down Expand Up @@ -525,6 +526,10 @@ public long getIndexIdFromKey(StaticBuffer key) {
return IndexRecordUtil.getIndexIdFromKey(key, hashKeys, hashLength);
}

public CompositeIndexInfo getIndexInfoFromKey(StaticBuffer key, Function<Long, CompositeIndexType> compositeIndexTypeFunction) {
return IndexRecordUtil.getIndexInfoFromKey(serializer, compositeIndexTypeFunction, key, hashKeys, hashLength);
}

public StaticBuffer getIndexKey(CompositeIndexType index, Map<String, Object> fieldValues) {
return IndexRecordUtil.getIndexKey(index, fieldValues, serializer, hashKeys, hashLength);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.RelationType;
import org.janusgraph.core.VertexLabel;
import org.janusgraph.core.schema.CompositeIndexInfo;
import org.janusgraph.core.schema.ConsistencyModifier;
import org.janusgraph.core.schema.EdgeLabelMaker;
import org.janusgraph.core.schema.Index;
Expand Down Expand Up @@ -566,7 +567,7 @@ public String getIndexKey(String indexName, Map<String, Object> fieldValues) {
}

@Override
public CompositeIndexType getIndexInfo(String hexString) throws DecoderException {
public CompositeIndexInfo getIndexInfo(String hexString) throws DecoderException {
StaticArrayBuffer indexKey = StaticArrayBuffer.of(Hex.decodeHex(hexString));
return transaction.getCompositeIndexInfo(indexKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package org.janusgraph.graphdb.database.util;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
Expand All @@ -27,6 +28,7 @@
import org.janusgraph.core.JanusGraphVertex;
import org.janusgraph.core.JanusGraphVertexProperty;
import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.schema.CompositeIndexInfo;
import org.janusgraph.core.schema.SchemaStatus;
import org.janusgraph.diskstorage.Entry;
import org.janusgraph.diskstorage.ReadBuffer;
Expand Down Expand Up @@ -367,8 +369,36 @@ public static StaticBuffer getIndexKey(CompositeIndexType index, Object[] values
}

public static long getIndexIdFromKey(StaticBuffer key, boolean hashKeys, HashingUtil.HashLength hashLength) {
if (hashKeys) key = HashingUtil.getKey(hashLength,key);
return VariableLong.readPositive(key.asReadBuffer());
ReadBuffer readBuffer = getIndexKeyReadBuffer(key, hashKeys, hashLength);
return VariableLong.readPositive(readBuffer);
}

public static CompositeIndexInfo getIndexInfoFromKey(Serializer serializer,
Function<Long, CompositeIndexType> compositeIndexTypeFunction,
StaticBuffer key,
boolean hashKeys,
HashingUtil.HashLength hashLength) {

ReadBuffer readBuffer = getIndexKeyReadBuffer(key, hashKeys, hashLength);
long indexId = VariableLong.readPositive(readBuffer);//read index id
CompositeIndexType compositeIndexType = compositeIndexTypeFunction.apply(indexId);
IndexField[] fieldKeys = compositeIndexType.getFieldKeys();
Object[] values = new Object[fieldKeys.length];
for (int i = 0; i < fieldKeys.length; i++) {
IndexField f = fieldKeys[i];
if (InternalAttributeUtil.hasGenericDataType(f.getFieldKey())) {
values[i] = serializer.readClassAndObject(readBuffer);
} else {
values[i] = serializer.readObjectNotNull(readBuffer, f.getFieldKey().dataType());
}

}
return new CompositeIndexInfo(compositeIndexType, values);
}

private static ReadBuffer getIndexKeyReadBuffer(StaticBuffer key, boolean hashKeys, HashingUtil.HashLength hashLength) {
if (hashKeys) key = HashingUtil.getKey(hashLength, key);
return key.asReadBuffer();
}

public static IndexUpdate<StaticBuffer, Entry> getCompositeIndexUpdate(CompositeIndexType index, IndexMutationType indexMutationType, IndexRecordEntry[] record,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.janusgraph.core.SchemaViolationException;
import org.janusgraph.core.VertexLabel;
import org.janusgraph.core.attribute.Cmp;
import org.janusgraph.core.schema.CompositeIndexInfo;
import org.janusgraph.core.schema.ConsistencyModifier;
import org.janusgraph.core.schema.EdgeLabelMaker;
import org.janusgraph.core.schema.JanusGraphSchemaElement;
Expand Down Expand Up @@ -1258,19 +1259,24 @@ public StaticBuffer getCompositeIndexKey(String indexName, Map<String, Object> f
}
}

public CompositeIndexType getCompositeIndexInfo(StaticArrayBuffer indexKey) {
long schemaVertexId = indexSerializer.getIndexIdFromKey(indexKey);
InternalVertex typeVertex = vertexCache.get(schemaVertexId, existingVertexRetriever);
public CompositeIndexInfo getCompositeIndexInfo(StaticArrayBuffer indexKey) {

Preconditions.checkNotNull(typeVertex, "Index with key [" + indexKey + "] was not found");
JanusGraphSchemaVertex schemaVertex = (JanusGraphSchemaVertex) typeVertex;
com.google.common.base.Function<Long, CompositeIndexType> compositeIndexTypeFunction = input -> {
long schemaVertexId = indexSerializer.getIndexIdFromKey(indexKey);
InternalVertex typeVertex = vertexCache.get(schemaVertexId, existingVertexRetriever);

IndexType indexType = schemaVertex.asIndexType();
if (indexType instanceof CompositeIndexType) {
return (CompositeIndexType) indexType;
} else {
throw new IllegalArgumentException("Index with key [" + indexKey + "] is not a composite index");
}
Preconditions.checkNotNull(typeVertex, "Index with key [" + indexKey + "] was not found");
JanusGraphSchemaVertex schemaVertex = (JanusGraphSchemaVertex) typeVertex;

IndexType indexType = schemaVertex.asIndexType();
if (indexType instanceof CompositeIndexType) {
return (CompositeIndexType) indexType;
} else {
throw new IllegalArgumentException("Index with key [" + indexKey + "] is not a composite index");
}
};

return indexSerializer.getIndexInfoFromKey(indexKey, compositeIndexTypeFunction);
}

@Override
Expand Down

1 comment on commit 46a971a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 46a971a Previous: 53a5332 Ratio
org.janusgraph.JanusGraphSpeedBenchmark.basicAddAndDelete 12826.45762444034 ms/op 12606.637936248144 ms/op 1.02
org.janusgraph.GraphCentricQueryBenchmark.getVertices 984.6059746698736 ms/op 933.707013771124 ms/op 1.05
org.janusgraph.MgmtOlapJobBenchmark.runClearIndex 216.48705604565217 ms/op 216.42669925797105 ms/op 1.00
org.janusgraph.MgmtOlapJobBenchmark.runReindex 328.42056688035717 ms/op 325.2034199216667 ms/op 1.01
org.janusgraph.JanusGraphSpeedBenchmark.basicCount 236.80652206388137 ms/op 241.37535189160565 ms/op 0.98
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesAllPropertiesWithAllMultiQuerySlicesUnderMaxRequestsPerConnection 4720.682907629702 ms/op 4702.35119956595 ms/op 1.00
org.janusgraph.CQLMultiQueryBenchmark.getElementsWithUsingEmitRepeatSteps 16865.897606632938 ms/op 16231.144626673333 ms/op 1.04
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesMultiplePropertiesWithSmallBatch 19837.08742481212 ms/op 18874.23529971717 ms/op 1.05
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.vertexCentricPropertiesFetching 58574.6883014 ms/op 57429.257257799996 ms/op 1.02
org.janusgraph.CQLMultiQueryDropBenchmark.dropVertices 1615.1723827580945 ms/op 1568.3338987479272 ms/op 1.03
org.janusgraph.CQLMultiQueryBenchmark.getAllElementsTraversedFromOuterVertex 7866.763507804693 ms/op 7848.466185459547 ms/op 1.00
org.janusgraph.CQLMultiQueryBenchmark.getVerticesWithDoubleUnion 379.3899148933959 ms/op 381.3076924089574 ms/op 0.99
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesAllPropertiesWithUnlimitedBatch 4099.468593604913 ms/op 3925.9151810796147 ms/op 1.04
org.janusgraph.CQLMultiQueryBenchmark.getNames 8334.44708276416 ms/op 7999.962392196457 ms/op 1.04
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesThreePropertiesWithAllMultiQuerySlicesUnderMaxRequestsPerConnection 5530.018967603963 ms/op 5428.037913477006 ms/op 1.02
org.janusgraph.CQLMultiQueryBenchmark.getLabels 7017.650680373439 ms/op 6696.0079414739175 ms/op 1.05
org.janusgraph.CQLMultiQueryBenchmark.getVerticesFilteredByAndStep 434.3910275876522 ms/op 448.75009294589086 ms/op 0.97
org.janusgraph.CQLMultiQueryBenchmark.getVerticesFromMultiNestedRepeatStepStartingFromSingleVertex 12663.921618160002 ms/op 12367.791196107844 ms/op 1.02
org.janusgraph.CQLMultiQueryBenchmark.getVerticesWithCoalesceUsage 368.8607968309453 ms/op 367.30972053799104 ms/op 1.00
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesMultiplePropertiesWithAllMultiQuerySlicesUnderMaxRequestsPerConnection 14179.442790288998 ms/op 14518.526449692697 ms/op 0.98
org.janusgraph.CQLMultiQueryBenchmark.getIdToOutVerticesProjection 249.43173327980628 ms/op 255.05417396928058 ms/op 0.98
org.janusgraph.CQLMultiQueryMultiSlicesBenchmark.getValuesMultiplePropertiesWithUnlimitedBatch 14492.278341740333 ms/op 14575.609847963999 ms/op 0.99
org.janusgraph.CQLCompositeIndexInlinePropBenchmark.searchVertices 1556.0727756139577 ms/op 1552.5877175318828 ms/op 1.00
org.janusgraph.CQLMultiQueryDropBenchmark.dropVerticesGremlinQuery 1589.6720600394513 ms/op 1585.1790679378414 ms/op 1.00
org.janusgraph.CQLMultiQueryBenchmark.getNeighborNames 8064.957365100146 ms/op 7881.313643353237 ms/op 1.02
org.janusgraph.CQLMultiQueryBenchmark.getElementsWithUsingRepeatUntilSteps 8970.325709197834 ms/op 8781.835625855028 ms/op 1.02
org.janusgraph.CQLMultiQueryBenchmark.getAdjacentVerticesLocalCounts 8200.84605934742 ms/op 8207.534452278742 ms/op 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.