All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ojalgo.array.OffHeapArray2 Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
/*
 * Copyright 1997-2015 Optimatika
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.ojalgo.array;

import java.lang.reflect.Field;

import org.ojalgo.access.Access1D;
import org.ojalgo.access.StructureAnyD;
import org.ojalgo.constant.PrimitiveMath;
import org.ojalgo.function.BinaryFunction;
import org.ojalgo.function.FunctionSet;
import org.ojalgo.function.NullaryFunction;
import org.ojalgo.function.UnaryFunction;
import org.ojalgo.function.VoidFunction;
import org.ojalgo.function.aggregator.AggregatorSet;
import org.ojalgo.scalar.PrimitiveScalar;

import sun.misc.Unsafe;

/**
 * Off heap memory array.
 *
 * @author apete
 * @deprecated Use OffHeapArray instead
 */
@Deprecated
final class OffHeapArray2 extends BasicArray {

    public static final ArrayFactory FACTORY = new ArrayFactory() {

        @Override
        public AggregatorSet aggregator() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public FunctionSet function() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public org.ojalgo.scalar.Scalar.Factory scalar() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        long getCapacityLimit() {
            return Long.MAX_VALUE;
        }

        @Override
        OffHeapArray2 makeStructuredZero(final long... structure) {
            return new OffHeapArray2(StructureAnyD.count(structure));
        }

        @Override
        OffHeapArray2 makeToBeFilled(final long... structure) {
            return new OffHeapArray2(StructureAnyD.count(structure));
        }

    };

    static Unsafe UNSAFE;

    static {

        Unsafe tmpUnsafe = null;

        try {
            final Field tmpField = Unsafe.class.getDeclaredField("theUnsafe");
            tmpField.setAccessible(true);
            tmpUnsafe = (Unsafe) tmpField.get(null);
        } catch (final Exception e) {
            tmpUnsafe = null;
        } finally {
            UNSAFE = tmpUnsafe;
        }
    }

    public static OffHeapArray2 make(final long count) {
        return new OffHeapArray2(count);
    }

    public static final SegmentedArray makeSegmented(final long count) {
        // return SegmentedArray.make(FACTORY, count);
        return FACTORY.makeSegmented(count);
    }

    private final long data;

    private final long myCount;

    OffHeapArray2(final long count) {

        super();

        myCount = count;

        data = UNSAFE.allocateMemory(Unsafe.ARRAY_DOUBLE_INDEX_SCALE * count);

        this.fillAll(PrimitiveMath.ZERO);
    }

    public void add(final long index, final double addend) {
        final long tmpAddress = this.address(index);
        final double tmpCurrentValue = UNSAFE.getDouble(tmpAddress);
        UNSAFE.putDouble(tmpAddress, tmpCurrentValue + addend);
    }

    public void add(final long index, final Number addend) {
        this.add(index, addend.doubleValue());
    }

    public long count() {
        return myCount;
    }

    public double doubleValue(final long index) {
        return UNSAFE.getDouble(this.address(index));
    }

    public void fillOne(final long index, final Access1D values, final long valueIndex) {
        this.set(index, values.doubleValue(valueIndex));
    }

    public void fillOne(final long index, final Double value) {
        this.set(index, value.doubleValue());
    }

    public void fillOne(final long index, final NullaryFunction supplier) {
        this.set(index, supplier.doubleValue());
    }

    public Double get(final long index) {
        return this.doubleValue(index);
    }

    public boolean isAbsolute(final long index) {
        return PrimitiveScalar.isAbsolute(this.doubleValue(index));
    }

    public boolean isSmall(final long index, final double comparedTo) {
        return PrimitiveScalar.isSmall(this.doubleValue(index), comparedTo);
    }

    public void modifyOne(final long index, final UnaryFunction modifier) {
        final long tmpAddress = this.address(index);
        final double tmpCurrentValue = UNSAFE.getDouble(tmpAddress);
        UNSAFE.putDouble(tmpAddress, modifier.invoke(tmpCurrentValue));
    }

    @Override
    public final void reset() {
        this.fillAll(PrimitiveMath.ZERO);
    }

    public void set(final long index, final double value) {
        UNSAFE.putDouble(this.address(index), value);
    }

    public void set(final long index, final Number value) {
        this.set(index, value.doubleValue());
    }

    public void visitOne(final long index, final VoidFunction visitor) {
        visitor.accept(this.doubleValue(index));
    }

    private final long address(final long index) {
        return data + (index * Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
    }

    private final long increment(final long step) {
        return step * Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
    }

    @Override
    protected void exchange(final long firstA, final long firstB, final long step, final long count) {

        long tmpIndexA = firstA;
        long tmpIndexB = firstB;

        double tmpVal;

        for (long i = 0; i < count; i++) {

            tmpVal = this.doubleValue(tmpIndexA);
            this.set(tmpIndexA, this.doubleValue(tmpIndexB));
            this.set(tmpIndexB, tmpVal);

            tmpIndexA += step;
            tmpIndexB += step;
        }
    }

    @Override
    protected void fill(final long first, final long limit, final long step, final Double value) {
        final long tmpFirst = this.address(first);
        final long tmpLimit = this.address(limit);
        final long tmpStep = this.increment(step);
        final double tmpValue = value.doubleValue();
        for (long a = tmpFirst; a < tmpLimit; a += tmpStep) {
            UNSAFE.putDouble(a, tmpValue);
        }
    }

    @Override
    protected void fill(final long first, final long limit, final long step, final NullaryFunction supplier) {
        final long tmpFirst = this.address(first);
        final long tmpLimit = this.address(limit);
        final long tmpStep = this.increment(step);
        for (long a = tmpFirst; a < tmpLimit; a += tmpStep) {
            UNSAFE.putDouble(a, supplier.doubleValue());
        }
    }

    @Override
    protected void finalize() throws Throwable {
        UNSAFE.freeMemory(data);
    }

    @Override
    protected boolean isSmall(final long first, final long limit, final long step, final double comparedTo) {

        boolean retVal = true;

        for (long i = first; retVal && (i < limit); i += step) {
            retVal &= PrimitiveScalar.isSmall(comparedTo, this.doubleValue(i));
        }

        return retVal;
    }

    @Override
    protected void modify(final long first, final long limit, final long step, final Access1D left, final BinaryFunction function) {
        long tmpAddress;
        for (long i = first; i < limit; i += step) {
            tmpAddress = this.address(i);
            UNSAFE.putDouble(tmpAddress, function.invoke(left.doubleValue(i), UNSAFE.getDouble(tmpAddress)));
        }
    }

    @Override
    protected void modify(final long first, final long limit, final long step, final BinaryFunction function, final Access1D right) {
        long tmpAddress;
        for (long i = first; i < limit; i += step) {
            tmpAddress = this.address(i);
            UNSAFE.putDouble(tmpAddress, function.invoke(UNSAFE.getDouble(tmpAddress), right.doubleValue(i)));
        }
    }

    @Override
    protected void modify(final long first, final long limit, final long step, final UnaryFunction function) {
        final long tmpFirst = this.address(first);
        final long tmpLimit = this.address(limit);
        final long tmpStep = this.increment(step);
        for (long a = tmpFirst; a < tmpLimit; a += tmpStep) {
            UNSAFE.putDouble(a, function.invoke(UNSAFE.getDouble(a)));
        }
    }

    @Override
    protected void visit(final long first, final long limit, final long step, final VoidFunction visitor) {
        final long tmpFirst = this.address(first);
        final long tmpLimit = this.address(limit);
        final long tmpStep = this.increment(step);
        for (long a = tmpFirst; a < tmpLimit; a += tmpStep) {
            visitor.invoke(UNSAFE.getDouble(a));
        }
    }

    @Override
    boolean isPrimitive() {
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy