/*
* 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;
}
}