net.sf.ehcache.store.disk.ods.Region Maven / Gradle / Ivy
Show all versions of ehcache Show documentation
/**
* Copyright Terracotta, Inc.
*
* 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 net.sf.ehcache.store.disk.ods;
/**
* Class that represents the regions held within this set.
*
* @author Chris Dennis
*/
public class Region extends AATreeSet.AbstractTreeNode implements Comparable {
private long start;
private long end;
private long contiguous;
/**
* Creates a region containing just the single given value
* @param value
*/
public Region(long value) {
this(value, value);
}
/**
* Creates a region containing the given range of value (inclusive).
*/
public Region(long start, long end) {
super();
this.start = start;
this.end = end;
updateContiguous();
}
/**
* Create a shallow copy of a region.
*
* The new Region has NULL left and right children.
*/
public Region(Region r) {
this(r.start(), r.end());
}
/**
* Return the size of the largest region linked from this node.
*/
public long contiguous() {
if (getLeft().getPayload() == null && getRight().getPayload() == null) {
return size();
} else {
return contiguous;
}
}
private void updateContiguous() {
Region left = (Region) getLeft().getPayload();
Region right = (Region) getRight().getPayload();
long leftContiguous = left == null ? 0 : left.contiguous();
long rightContiguous = right == null ? 0 : right.contiguous();
contiguous = Math.max(size(), Math.max(leftContiguous, rightContiguous));
}
@Override
public void setLeft(AATreeSet.Node l) {
super.setLeft(l);
updateContiguous();
}
@Override
public void setRight(AATreeSet.Node r) {
super.setRight(r);
updateContiguous();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "Range(" + this.start + "," + this.end + ")" + " contiguous:" + this.contiguous();
}
/**
* Returns the size of this range (the number of values within its bounds).
*/
public long size() {
// since it is all inclusive
return (isNull() ? 0 : this.end - this.start + 1);
}
/**
* Return true if this region is null, i.e. represents no valid range.
*/
protected boolean isNull() {
return this.start > this.end;
}
/**
* Remove the supplied region from this region.
*
* @param r region to remove
* @return a possible extra region to be added, or null if none is required
* @throws IllegalArgumentException if this region does not completely enclose the supplied region
*/
protected Region remove(Region r) throws IllegalArgumentException {
if (r.start < this.start || r.end > this.end) {
throw new IllegalArgumentException("Ranges : Illegal value passed to remove : " + this + " remove called for : " + r);
}
if (this.start == r.start) {
this.start = r.end + 1;
updateContiguous();
return null;
} else if (this.end == r.end) {
this.end = r.start - 1;
updateContiguous();
return null;
} else {
Region newRegion = new Region(r.end + 1, this.end);
this.end = r.start - 1;
updateContiguous();
return newRegion;
}
}
/**
* Merge the supplied region into this region (if they are adjoining).
*
* @param r region to merge
* @throws IllegalArgumentException if the regions are not adjoining
*/
protected void merge(Region r) throws IllegalArgumentException {
if (this.start == r.end + 1) {
this.start = r.start;
} else if (this.end == r.start - 1) {
this.end = r.end;
} else {
throw new IllegalArgumentException("Ranges : Merge called on non contiguous values : [this]:" + this + " and " + r);
}
updateContiguous();
}
/**
* {@inheritDoc}
*/
public int compareTo(Comparable other) {
if (other instanceof Region) {
return compareTo((Region) other);
} else if (other instanceof Long) {
return compareTo((Long) other);
} else {
throw new AssertionError("Unusual Type " + other.getClass());
}
}
private int compareTo(Region r) {
if (this.start > r.start || this.end > r.end) {
return 1;
} else if (this.start < r.start || this.end < r.end) {
return -1;
} else {
return 0;
}
}
private int compareTo(Long l) {
if (l.longValue() > end) {
return -1;
} else if (l.longValue() < start) {
return 1;
} else {
return 0;
}
}
/**
* {@inheritDoc}
*/
public void swapPayload(AATreeSet.Node other) {
if (other instanceof Region) {
Region r = (Region) other;
long temp = this.start;
this.start = r.start;
r.start = temp;
temp = this.end;
this.end = r.end;
r.end = temp;
updateContiguous();
} else {
throw new AssertionError();
}
}
/**
* {@inheritDoc}
*/
public Region getPayload() {
return this;
}
/**
* Returns the start of this range (inclusive).
*/
public long start() {
return start;
}
/**
* Returns the end of this range (inclusive).
*/
public long end() {
return end;
}
}