Java tutorial
// Copyright 2017 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.graphdb.database.idassigner.placement; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import org.janusgraph.core.JanusGraphProperty; import org.janusgraph.core.JanusGraphVertex; import org.janusgraph.core.JanusGraphVertexProperty; import org.janusgraph.diskstorage.configuration.ConfigOption; import org.janusgraph.diskstorage.configuration.Configuration; import org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration; import org.janusgraph.graphdb.configuration.PreInitializeConfigOptions; import org.janusgraph.graphdb.database.idassigner.IDPoolExhaustedException; import org.janusgraph.graphdb.idmanagement.IDManager; import org.janusgraph.graphdb.internal.InternalElement; import org.janusgraph.graphdb.internal.InternalVertex; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * @author Matthias Broecheler (me@matthiasb.com) */ @PreInitializeConfigOptions public class PropertyPlacementStrategy extends SimpleBulkPlacementStrategy { private static final Logger log = LoggerFactory.getLogger(PropertyPlacementStrategy.class); public static final ConfigOption<String> PARTITION_KEY = new ConfigOption<String>( GraphDatabaseConfiguration.IDS_NS, "partition-key", "Partitions the graph by properties of this key", ConfigOption.Type.MASKABLE, String.class, key -> StringUtils.isNotBlank(key)); private String key; private IDManager idManager; public PropertyPlacementStrategy(Configuration config) { super(config); setPartitionKey(config.get(PARTITION_KEY)); } public PropertyPlacementStrategy(String key, int concurrentPartitions) { super(concurrentPartitions); setPartitionKey(key); } public void setPartitionKey(String key) { Preconditions.checkArgument(StringUtils.isNotBlank(key), "Invalid key configured: %s", key); this.key = key; } @Override public void injectIDManager(IDManager idManager) { Preconditions.checkNotNull(idManager); this.idManager = idManager; } @Override public int getPartition(InternalElement element) { if (element instanceof JanusGraphVertex) { int pid = getPartitionIDbyKey((JanusGraphVertex) element); if (pid >= 0) return pid; } return super.getPartition(element); } @Override public void getPartitions(Map<InternalVertex, PartitionAssignment> vertices) { super.getPartitions(vertices); for (Map.Entry<InternalVertex, PartitionAssignment> entry : vertices.entrySet()) { int pid = getPartitionIDbyKey(entry.getKey()); if (pid >= 0) ((SimplePartitionAssignment) entry.getValue()).setPartitionID(pid); } } private int getPartitionIDbyKey(JanusGraphVertex vertex) { Preconditions.checkState(idManager != null && key != null, "PropertyPlacementStrategy has not been initialized correctly"); assert idManager.getPartitionBound() <= Integer.MAX_VALUE; int partitionBound = (int) idManager.getPartitionBound(); JanusGraphVertexProperty p = (JanusGraphVertexProperty) Iterables .getFirst(vertex.query().keys(key).properties(), null); if (p == null) return -1; int hashPid = Math.abs(p.value().hashCode()) % partitionBound; assert hashPid >= 0 && hashPid < partitionBound; if (isExhaustedPartition(hashPid)) { //We keep trying consecutive partition ids until we find a non-exhausted one int newPid = hashPid; do { newPid = (newPid + 1) % partitionBound; if (newPid == hashPid) //We have gone full circle - no more ids to try throw new IDPoolExhaustedException("Could not find non-exhausted partition"); } while (isExhaustedPartition(newPid)); return newPid; } else return hashPid; } }