org.piax.gtrans.ov.ring.rq.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: MSkipGraph.java 1160 2015-03-15 02:43:20Z teranisi $
*/
package org.piax.gtrans.ov.ring.rq;
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: 開区間(..)に対して厳密な考慮はされていない.
*/
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 type of comparable.
* @param r the range.
* @param a the left side key.
* @param b the right side key.
* @return the removed range.
*/
public static > Range removedRange(Range r, K a, K b) {
// this method can be replaced with the followings snippet but
// we have not tested the new code so ...
/*
Range another = new Range<>(a, true, b, false);
List> removed = new ArrayList<>();
r.retain(another, removed);
if (removed.isEmpty()) {
return null;
}
if (removed.size() != 1) {
throw new Error("mulitple results");
}
return removed.get(0);
*/
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;
}
}
public 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(true, prev.from,
prev.fromInclusive, r.to, r.toInclusive);
} else {
merged.add(prev);
prev = r;
}
}
if (prev != null) {
merged.add(prev);
}
return merged;
}
}