/* * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 com.amazonaws.geo.model; import java.util.ArrayList; import java.util.List; import com.amazonaws.geo.GeoDataManagerConfiguration; import com.amazonaws.geo.s2.internal.S2Manager; public class GeohashRange { private long rangeMin; private long rangeMax; public GeohashRange(long range1, long range2) { this.rangeMin = Math.min(range1, range2); this.rangeMax = Math.max(range1, range2); } public boolean tryMerge(GeohashRange range) { if (range.getRangeMin() - this.rangeMax <= GeoDataManagerConfiguration.MERGE_THRESHOLD && range.getRangeMin() - this.rangeMax > 0) { this.rangeMax = range.getRangeMax(); return true; } if (this.rangeMin - range.getRangeMax() <= GeoDataManagerConfiguration.MERGE_THRESHOLD && this.rangeMin - range.getRangeMax() > 0) { this.rangeMin = range.getRangeMin(); return true; } return false; } /* * Try to split the range to multiple ranges based on the hash key. * * e.g., for the following range: * * min: 123456789 * max: 125678912 * * when the hash key length is 3, we want to split the range to: * * 1 * min: 123456789 * max: 123999999 * * 2 * min: 124000000 * max: 124999999 * * 3 * min: 125000000 * max: 125678912 * * For this range: * * min: -125678912 * max: -123456789 * * we want: * * 1 * min: -125678912 * max: -125000000 * * 2 * min: -124999999 * max: -124000000 * * 3 * min: -123999999 * max: -123456789 */ public List<GeohashRange> trySplit(int hashKeyLength) { List<GeohashRange> result = new ArrayList<GeohashRange>(); long minHashKey = S2Manager.generateHashKey(rangeMin, hashKeyLength); long maxHashKey = S2Manager.generateHashKey(rangeMax, hashKeyLength); long denominator = (long) Math.pow(10, String.valueOf(rangeMin).length() - String.valueOf(minHashKey).length()); if (minHashKey == maxHashKey) { result.add(this); } else { for (long l = minHashKey; l <= maxHashKey; l++) { if (l > 0) { result.add(new GeohashRange(l == minHashKey ? rangeMin : l * denominator, l == maxHashKey ? rangeMax : (l + 1) * denominator - 1)); } else { result.add(new GeohashRange(l == minHashKey ? rangeMin : (l - 1) * denominator + 1, l == maxHashKey ? rangeMax : l * denominator)); } } } return result; } public long getRangeMin() { return rangeMin; } public void setRangeMin(long rangeMin) { this.rangeMin = rangeMin; } public long getRangeMax() { return rangeMax; } public void setRangeMax(long rangeMax) { this.rangeMax = rangeMax; } }