/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.usergrid.persistence.core.shard; import com.google.common.hash.Funnel; /** * An algorithm that will generate all possible keys for different "Levels" of sharding. For instance, imagine this * scheme. * * 1 Shard 2 Shards 4 Shards 8 Shards * * (note that we do not need to expand by 2x each time, this is merely an example). * * When seeking on a string key, for 4 levels of the key, we get 4 different keys due to different shard sizes. This is * faster than seeking ALL shards, since this would result in 15 shards, vs 4 in the example. */ public class ExpandingShardLocator<T> { private final ShardLocator<T>[] shardLocatorList; /** * Create a new instance with the specified history. For instance, from the javadoc above, the constructor would * contains {8, 4, 3, 2, 1}. Shards are returned in the size order they are given in the constructor */ public ExpandingShardLocator( final Funnel<T> funnel, final int... bucketSizes ) { shardLocatorList = new ShardLocator[bucketSizes.length]; for ( int i = 0; i < bucketSizes.length; i++ ) { shardLocatorList[i] = new ShardLocator<>( funnel, bucketSizes[i] ); } } /** * Hash the results, and return them in the same order as specified in the constructor */ public int[] getAllBuckets( T hash ) { int[] results = new int[shardLocatorList.length]; for ( int i = 0; i < shardLocatorList.length; i++ ) { results[i] = shardLocatorList[i].getBucket( hash ); } return results; } /** * Get the current bucket for the hash value. Hashes from the first element in the list */ public int getCurrentBucket( T hash ) { return shardLocatorList[0].getBucket( hash ); } }