/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package ru.malik.elaborarer.avtoo.lang;
import avt.lang.array.*;
public abstract class ObjectStorage(Storage, Cloneable, Measureable, ObjectArray)
{
private long[] fldHashs;
private Object[] fldArray;
protected () {
long[] hashs = new long[0x3f];
Object[] array = newArray(0x3f);
hashs.length = array.length = 0;
fldHashs = hashs;
fldArray = array;
fldData = array;
setArray(array);
}
protected (ObjectStorage source) {
long[] hashs = source.fldHashs;
Object[] array = source.fldArray;
int capacity = array.capacity;
int length = array.length;
Array.copy(hashs, 0, hashs = new long[capacity], 0, hashs.length = length);
Array.copy(array, 0, array = newArray(capacity), 0, array.length = length);
fldHashs = hashs;
fldArray = array;
fldData = array;
setArray(array);
}
public abstract ObjectStorage clone();
public abstract Object operator [](int index);
protected abstract void setArray(Object[] array);
protected abstract Object getEmpty();
protected abstract Object[] newArray(int capacity);
protected int indexOf(Object item) {
if(item != null || (item = getEmpty()) != null)
{
Object[] array = fldArray;
{
int index = Array.indexOf(item, array, 0, 0);
if(index >= 0) return index;
}
for(long[] hashs = fldHashs, long hash = item.hashCodeAsLong(), int index = -1; (index = Array.indexOf(hash, hashs, index + 1, 0)) >= 0; )
{
if(item.equals(array[index])) return index;
}
}
return -1;
}
protected int indexAcquire(Object item) {
if(item != null || (item = getEmpty()) != null)
{
int result = indexOf(item);
if(result < 0)
{
long[] hashs = fldHashs;
Object[] array = fldArray;
if((result = array.length) == array.capacity)
{
if(result == Int.MAX_VALUE)
{
throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
}
int capacity = result << 1 | 1;
Array.copy(hashs, 0, hashs = new long[capacity], 0, result);
Array.copy(array, 0, array = newArray(capacity), 0, result);
fldHashs = hashs;
fldArray = array;
fldData = array;
setArray(array);
}
hashs.length = array.length = result + 1;
hashs[result] = item.hashCodeAsLong();
array[result] = item;
}
return result;
}
return -1;
}
}