org.piax.gtrans.ov.sg.RangeUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of piax-compat Show documentation
Show all versions of piax-compat Show documentation
A backward compatibility package for PIAX
The newest version!
/*
* RangeUtils.java - RangeUtils implementation of SkipGraph.
*
* Copyright (c) 2015 Kota Abe / PIAX development team
*
* You can redistribute it and/or modify it under either the terms of
* the AGPLv3 or PIAX binary code license. See the file COPYING
* included in the PIAX package for more in detail.
*
* $Id: RangeUtils.java 1176 2015-05-23 05:56:40Z teranisi $
*/
package org.piax.gtrans.ov.sg;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.piax.common.DdllKey;
import org.piax.common.subspace.Range;
import org.piax.gtrans.ov.ddll.Node;
import org.piax.util.KeyComparator;
/**
* A utility class for range manipulations.
* Note: 開区間(..)に対して厳密な考慮はされていない.
*
* @author k-abe
*/
public class RangeUtils {
private static KeyComparator keyComp = KeyComparator.getInstance();
/**
* Range r から,[a, b) の区間を削除し,残った Range を返す.
* aはrの外側にあるか,aはrの左端と等しい必要がある (手抜き).
* 残らない場合は null が返される.
*
* r [-------------------)
* [a--------------b)
* [--ret---)
*
* @param the comparable type.
* @param r the range.
* @param a the left value.
* @param b the right value.
* @return the range.
*/
static > Range retainRange(Range r, K a, K b) {
if (r.contains(a) && keyComp.compare(a, r.from) != 0) {
throw new Error("a is in r");
}
if (Node.isOrdered(a, r.from, b) && keyComp.compare(r.from, b) != 0) {
// Range [-----------)
// a-----..
if (Node.isOrdered(a, r.to, b) && !r.contains(b)) {
// empty
return null;
} else {
// Range [-----------)
// a------b
// -------b a--
return new Range(b, true, r.to, r.toInclusive);
}
} else {
// Range [------)
// a--b
// --b a-
return r;
}
}
/**
* Range r から,[a, b) の区間を削除したときの,削除された Range を返す.
* aはrの外側にあるか,aはrの左端と等しい必要がある (手抜き).
* 削除されない場合は null が返る.
*
* r [-------------------)
* [a--------------b)
* [---ret----)
*
* @param the type of comparable.
* @param r the range.
* @param a the left value.
* @param b the right value.
* @return the range.
*/
static > Range removedRange(Range r, K a, K b) {
if (r.contains(a) && keyComp.compare(a, r.from) != 0) {
throw new Error("a is in r");
}
if (Node.isOrdered(a, r.from, b) && keyComp.compare(r.from, b) != 0) {
// Range [-----------)
// a-----..
if (Node.isOrdered(a, r.to, b) && !r.contains(b)) {
// empty
return r;
} else {
// Range [-----------)
// a------b
// -------b a--
return new Range(r.from, r.fromInclusive, b, true);
}
} else {
// Range [------)
// a--b
// --b a-
return null;
}
}
static List> concatAdjacentRanges(List> ranges) {
Collections.sort(ranges, new Comparator>() {
@Override
public int compare(Range> o1, Range> o2) {
return keyComp.compare(o1.from, o2.from);
}
});
List> merged = new ArrayList>();
Range prev = null;
for (Range r : ranges) {
if (prev == null) {
prev = r;
} else if (prev.to.compareTo(r.from) == 0) {
prev =
new Range(prev.from, prev.fromInclusive, r.to,
r.toInclusive);
} else {
merged.add(prev);
prev = r;
}
}
if (prev != null) {
merged.add(prev);
}
return merged;
}
static > boolean hasCommon(Range range,
K from, K to) {
return (Node.isOrdered(from, range.from, to)
|| Node.isOrdered(from, range.to, to));
}
}