blob: 2cde639898db8f454d0ffde0f1bb15fffa4e5720 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2019, 2020 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.jcommons.collections;
import java.util.Arrays;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
/**
* For integer arrays with distinguish intervals in increasing order:
* [startOffset<sub>0</sub>, endOffset<sub>0</sub>), [startOffset<sub>1</sub>, endOffset<sub>2</sub>), ...
*/
@NonNullByDefault
public class IntIntervalArrays {
/**
* Inserts blank (non-marked range).
*
* The method may changed the array specified by <code>regions</code>!
*
* @param regions the regions
* @param offset the offset of the blank to insert
* @param length the length of the blank to insert
* @return
*/
public static int[] insertBlank(int[] regions, final int offset, final int length) {
int i= 0;
for (;; i++) {
if (i >= regions.length) {
return regions;
}
if (regions[i] < offset) {
continue;
}
else {
break;
}
}
if (i % 2 == 1) { // region is open
if (regions[i] == offset) { // -> merge
i++;
}
else /*(regions[i] > startOffset)*/ { // -> split region
regions= Arrays.copyOf(regions, regions.length + 2);
System.arraycopy(regions, i, regions, i + 2, regions.length - (i + 2));
regions[i++]= offset;
regions[i++]= offset + length;
}
}
while (i < regions.length) {
regions[i++]+= length;
}
return regions;
}
/**
* Inserts region (marked range).
*
* The method may changed the array specified by <code>regions</code>!
*
* @param regions the regions
* @param offset the offset of the region to insert
* @param length the length of the region to insert
* @return
*/
public static int[] insertRegion(int[] regions, final int offset, final int length) {
int i= 0;
for (;; i++) {
if (i >= regions.length) { // -> append new region
regions= Arrays.copyOf(regions, regions.length + 2);
regions[i++]= offset;
regions[i++]= offset + length;
return regions;
}
if (regions[i] < offset) {
continue;
}
else {
break;
}
}
if (i % 2 == 0) { // no region open
if (regions[i] == offset) { // -> merge
i++;
}
else /*(regions[i] > startOffset)*/ { // -> insert region
regions= Arrays.copyOf(regions, regions.length + 2);
System.arraycopy(regions, i, regions, i + 2, regions.length - (i + 2));
regions[i++]= offset;
regions[i++]= offset + length;
}
}
while (i < regions.length) {
regions[i++]+= length;
}
return regions;
}
/**
* Removes regions (marked ranges) behind the specified offset.
*
* The method may changed the array specified by <code>regions</code>!
*
* @param regions the regions
* @param offset the offset
* @return
*/
public static int[] removeTail(int[] regions, final int offset) {
int i= 0;
for (;; i++) {
if (i >= regions.length) {
return regions;
}
if (regions[i] < offset) {
continue;
}
else {
break;
}
}
if (i % 2 == 1) { // region is open
regions[i]= offset;
i++;
}
if (i < regions.length) {
regions= Arrays.copyOf(regions, i);
}
return regions;
}
private IntIntervalArrays() {
}
}