/*
* Copyright 2003-2014 JetBrains s.r.o.
*
* 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 jetbrains.mps.editor.runtime.style;
import jetbrains.mps.util.IndexableObjectSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class StyleMap<T> {
public int[] indexes = new int[0];
public Object[] values = new Object[0];
public static boolean isEmpty(int pointer) {
assert pointer != -1;
return pointer < 0;
}
public Object get(int pointer) {
if (isEmpty(pointer)) {
return null;
} else {
return values[pointer];
}
}
/**
* @return new pointer value
*/
protected int insert(int index, int pointer, Object value) {
assert isEmpty(pointer);
pointer = - pointer - 2;
int n = indexes.length;
int[] newIndexes = new int[n + 1];
Object[] newValues = new Object[n + 1];
System.arraycopy(indexes, 0, newIndexes, 0, pointer);
System.arraycopy(values, 0, newValues, 0, pointer);
newIndexes[pointer] = index;
newValues[pointer] = value;
System.arraycopy(indexes, pointer, newIndexes, pointer + 1, n - pointer);
System.arraycopy(values, pointer, newValues, pointer + 1, n - pointer);
indexes = newIndexes;
values = newValues;
return pointer;
}
/**
* @return new pointer value
*/
public int set(int index, int pointer, Object value) {
if (value == null) {
if (!isEmpty(pointer)) {
return delete(pointer);
} else {
return pointer;
}
} else {
if (isEmpty(pointer)) {
return insert(index, pointer, value);
} else {
values[pointer] = value;
return pointer;
}
}
}
/**
* @return new pointer value
*/
protected int delete(int pointer) {
assert !isEmpty(pointer);
int n = indexes.length;
int[] newIndexes = new int[n - 1];
Object[] newValues = new Object[n - 1];
System.arraycopy(indexes, 0, newIndexes, 0, pointer);
System.arraycopy(values, 0, newValues, 0, pointer);
System.arraycopy(indexes, pointer + 1, newIndexes, pointer, n - pointer - 1);
System.arraycopy(values, pointer + 1, newValues, pointer, n - pointer - 1);
indexes = newIndexes;
values = newValues;
pointer = - pointer - 2;
return pointer;
}
// pointer < -1 => empty, insert at (- myPointer - 2)
// pointer > -1 => exists, insert at (myPointer)
// pointer == -1 => reserved for single element
public int search(int index) {
int pointer = Arrays.binarySearch(indexes, index);
if (pointer >= 0) {
return pointer;
} else {
return pointer - 1;
}
}
public void setValue(int index, T value) {
set(index, search(index), value);
}
public int[] getIndexes() {
return indexes;
}
}