ObjectStorage.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Компилятор языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    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;
    }
}