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

net.algart.arrays.ArraysByteTableGetDataOp Maven / Gradle / Ivy

Go to download

Open-source Java libraries, supporting generalized smart arrays and matrices with elements of any types, including a wide set of 2D-, 3D- and multidimensional image processing and other algorithms, working with arrays and matrices.

There is a newer version: 1.4.23
Show newest version
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
 *
 * 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 net.algart.arrays;

/*Repeat.SectionStart main*/

import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

import net.algart.math.functions.Func;

/**
 * 

Implementation of {@link Array#getData(long, Object, int, int)} methods * in the custom implementations of functional arrays for one-argument functions and {@link ByteArray} argument. * Used by {@link ArraysFuncImpl} class.

* *

This class is immutable and thread-safe.

* * @author Daniel Alievsky */ class ArraysByteTableGetDataOp { private final ReentrantLock lock = new ReentrantLock(); private final ByteArray x0; private final DataByteBuffer dBuf; boolean[] booleanTable; char[] charTable; byte[] byteTable; short[] shortTable; int[] intTable; long[] longTable; float[] floatTable; double[] doubleTable; private final int destElementTypeCode; ArraysByteTableGetDataOp(boolean truncateOverflows, ByteArray x0, Func f, int destElementTypeCode) { this.x0 = x0; this.dBuf = (DataByteBuffer) Arrays.bufferInternal(x0, DataBuffer.AccessMode.READ); // - necessary not only for performance, but also for the guarantee // that direct buffer really returns the references to the internal Java array switch (destElementTypeCode) { case ArraysFuncImpl.BIT_TYPE_CODE: { booleanTable = new boolean[256]; for (int k = 0; k < booleanTable.length; k++) { booleanTable[k] = f.get(k) != 0.0; } break; } case ArraysFuncImpl.CHAR_TYPE_CODE: { charTable = new char[256]; if (truncateOverflows) { for (int k = 0; k < charTable.length; k++) { int v = (int) f.get(k); charTable[k] = v < Character.MIN_VALUE ? Character.MIN_VALUE : v > Character.MAX_VALUE ? Character.MAX_VALUE : (char) v; } } else { for (int k = 0; k < charTable.length; k++) { charTable[k] = (char) (long) f.get(k); } } break; } //[[Repeat() byte ==> short;; // BYTE ==> SHORT;; // 0xFF ==> 0xFFFF]] case ArraysFuncImpl.BYTE_TYPE_CODE: { byteTable = new byte[256]; if (truncateOverflows) { for (int k = 0; k < byteTable.length; k++) { int v = (int) f.get(k); byteTable[k] = v < 0 ? (byte) 0 : v > 0xFF ? (byte) 0xFF : (byte) v; } } else { for (int k = 0; k < byteTable.length; k++) { byteTable[k] = (byte) (long) f.get(k); } } break; } //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] case ArraysFuncImpl.SHORT_TYPE_CODE: { shortTable = new short[256]; if (truncateOverflows) { for (int k = 0; k < shortTable.length; k++) { int v = (int) f.get(k); shortTable[k] = v < 0 ? (short) 0 : v > 0xFFFF ? (short) 0xFFFF : (short) v; } } else { for (int k = 0; k < shortTable.length; k++) { shortTable[k] = (short) (long) f.get(k); } } break; } //[[Repeat.AutoGeneratedEnd]] case ArraysFuncImpl.INT_TYPE_CODE: { intTable = new int[256]; if (truncateOverflows) { for (int k = 0; k < intTable.length; k++) { intTable[k] = (int) f.get(k); } } else { for (int k = 0; k < intTable.length; k++) { intTable[k] = (int) (long) f.get(k); } } break; } //[[Repeat() long ==> float,,double;; // LONG ==> FLOAT,,DOUBLE;; // \(double\)\s+ ==> ,, ]] case ArraysFuncImpl.LONG_TYPE_CODE: { longTable = new long[256]; for (int k = 0; k < longTable.length; k++) { longTable[k] = (long) f.get(k); } break; } //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] case ArraysFuncImpl.FLOAT_TYPE_CODE: { floatTable = new float[256]; for (int k = 0; k < floatTable.length; k++) { floatTable[k] = (float) f.get(k); } break; } case ArraysFuncImpl.DOUBLE_TYPE_CODE: { doubleTable = new double[256]; for (int k = 0; k < doubleTable.length; k++) { doubleTable[k] = f.get(k); } break; } //[[Repeat.AutoGeneratedEnd]] } this.destElementTypeCode = destElementTypeCode; } void getData(long arrayPos, Object destArray, int destArrayOffset, int count) { Objects.requireNonNull(destArray, "Null destArray argument"); if (count < 0) { throw new IllegalArgumentException("Negative number of loaded elements (" + count + ")"); } if (arrayPos < 0) { throw AbstractArray.rangeException(arrayPos, x0.length(), x0.getClass()); } if (arrayPos > x0.length() - count) { throw AbstractArray.rangeException(arrayPos + count - 1, x0.length(), x0.getClass()); } for (; count > 0; ) { int len; boolean usePool = false; byte[] data = null; try { final int from, to; usePool = !dBuf.isDirect(); if (usePool) { data = (byte[]) ArraysFuncImpl.BYTE_BUFFERS.requestArray(); len = Math.min(count, data.length); x0.getData(arrayPos, data, 0, len); from = 0; to = len; } else { // Synchronization is necessary to provide thread-safety. // In this case, the cost of synchronization is low: // buffer mapping work very quickly for direct buffers. lock.lock(); try { dBuf.map(arrayPos, count); len = dBuf.cnt(); assert len == dBuf.count() : "too large buffer"; data = dBuf.data(); from = dBuf.from(); to = dBuf.to(); } finally { // We may unlock here: data array is never modified for direct buffers. lock.unlock(); } } switch (destElementTypeCode) { //[[Repeat() BIT ==> CHAR,,BYTE,,SHORT,,INT,,LONG,,FLOAT,,DOUBLE;; // boolean ==> char,,byte,,short,,int,,long,,float,,double]] case ArraysFuncImpl.BIT_TYPE_CODE: { boolean[] dest = (boolean[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = booleanTable[data[j] & 0xFF]; } break; } //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]] case ArraysFuncImpl.CHAR_TYPE_CODE: { char[] dest = (char[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = charTable[data[j] & 0xFF]; } break; } case ArraysFuncImpl.BYTE_TYPE_CODE: { byte[] dest = (byte[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = byteTable[data[j] & 0xFF]; } break; } case ArraysFuncImpl.SHORT_TYPE_CODE: { short[] dest = (short[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = shortTable[data[j] & 0xFF]; } break; } case ArraysFuncImpl.INT_TYPE_CODE: { int[] dest = (int[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = intTable[data[j] & 0xFF]; } break; } case ArraysFuncImpl.LONG_TYPE_CODE: { long[] dest = (long[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = longTable[data[j] & 0xFF]; } break; } case ArraysFuncImpl.FLOAT_TYPE_CODE: { float[] dest = (float[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = floatTable[data[j] & 0xFF]; } break; } case ArraysFuncImpl.DOUBLE_TYPE_CODE: { double[] dest = (double[]) destArray; for (int j = from; j < to; j++, destArrayOffset++) { dest[destArrayOffset] = doubleTable[data[j] & 0xFF]; } break; } //[[Repeat.AutoGeneratedEnd]] default: throw new AssertionError("Illegal destElementTypeCode"); } } finally { if (usePool) { ArraysFuncImpl.BYTE_BUFFERS.releaseArray(data); } } arrayPos += len; count -= len; } } } /*Repeat.SectionEnd main*/




© 2015 - 2024 Weber Informatics LLC | Privacy Policy