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

io.deephaven.chunk.WritableCharChunk Maven / Gradle / Ivy

The newest version!
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.chunk;

import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.util.pools.MultiChunkPool;

import io.deephaven.util.type.TypeUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
// region FillWithNullValueImports
import static io.deephaven.util.QueryConstants.NULL_CHAR;
// endregion FillWithNullValueImports

// region BufferImports
import java.nio.Buffer;
import java.nio.CharBuffer;
// endregion BufferImports

import static io.deephaven.chunk.util.pools.ChunkPoolConstants.POOL_WRITABLE_CHUNKS;

/**
 * {@link WritableChunk} implementation for char data.
 */
public class WritableCharChunk extends CharChunk implements WritableChunk {

    @SuppressWarnings("rawtypes")
    private static final WritableCharChunk[] EMPTY_WRITABLE_CHAR_CHUNK_ARRAY = new WritableCharChunk[0];

    static  WritableCharChunk[] getEmptyChunkArray() {
        // noinspection unchecked
        return EMPTY_WRITABLE_CHAR_CHUNK_ARRAY;
    }

    public static  WritableCharChunk makeWritableChunk(int size) {
        if (POOL_WRITABLE_CHUNKS) {
            return MultiChunkPool.forThisThread().takeWritableCharChunk(size);
        }
        return new WritableCharChunk<>(makeArray(size), 0, size);
    }

    public static  WritableCharChunk makeWritableChunkForPool(int size) {
        return new WritableCharChunk<>(makeArray(size), 0, size) {
            @Override
            public void close() {
                MultiChunkPool.forThisThread().giveWritableCharChunk(this);
            }
        };
    }

    public static  WritableCharChunk writableChunkWrap(char[] data) {
        return writableChunkWrap(data, 0, data.length);
    }

    public static  WritableCharChunk writableChunkWrap(char[] data, int offset, int size) {
        return new WritableCharChunk<>(data, offset, size);
    }

    protected WritableCharChunk(char[] data, int offset, int capacity) {
        super(data, offset, capacity);
    }

    public final void set(int index, char value) {
        data[offset + index] = value;
    }

    public final void add(char value) {
        data[offset + size++] = value;
    }

    @Override
    public WritableCharChunk slice(int offset, int capacity) {
        ChunkHelpers.checkSliceArgs(size, offset, capacity);
        return new WritableCharChunk<>(data, this.offset + offset, capacity);
    }

    // region array
    /**
     * Get the data array backing this WritableCharChunk. The first element of this chunk corresponds to
     * {@code array()[arrayOffset()]}.
     * 

* This WritableCharChunk must never be {@link #close() closed} while the array may be in use externally, * because it must not be returned to any pool for re-use until that re-use is guaranteed to be exclusive. * * @return The backing data array */ public final char[] array() { return data; } /** * Get this WritableCharChunk's offset into the backing data array. The first element of this chunk corresponds to * {@code array()[arrayOffset()]}. * * @return The offset into the backing data array */ public final int arrayOffset() { return offset; } // endregion array // region FillWithNullValueImpl @Override public final void fillWithNullValue(final int offset, final int length) { fillWithValue(offset, length, NULL_CHAR); } // endregion FillWithNullValueImpl // region fillWithBoxedValue @Override public final void fillWithBoxedValue(int offset, int size, Object value) { fillWithValue(offset, size, TypeUtils.unbox((Character) value)); } // endregion fillWithBoxedValue public final void fillWithValue(final int offset, final int length, final char value) { final int netOffset = this.offset + offset; if (length >= SYSTEM_ARRAYFILL_THRESHOLD) { Arrays.fill(data, netOffset, netOffset + length, value); return; } for (int ii = 0; ii < length; ++ii) { data[netOffset + ii] = value; } } public final void appendTypedChunk(CharChunk src, int srcOffset, int length) { copyFromTypedChunk(src, srcOffset, size, length); size += length; } @Override public final void copyFromChunk(Chunk src, int srcOffset, int destOffset, int length) { final CharChunk typedSrc = src.asCharChunk(); copyFromTypedChunk(typedSrc, srcOffset, destOffset, length); } public final void copyFromTypedChunk(CharChunk src, int srcOffset, int destOffset, int length) { copyFromTypedArray(src.data, src.offset + srcOffset, destOffset, length); } @Override public final void copyFromArray(Object srcArray, int srcOffset, int destOffset, int length) { final char[] typedArray = (char[]) srcArray; copyFromTypedArray(typedArray, srcOffset, destOffset, length); } public final void copyFromTypedArray(char[] src, int srcOffset, int destOffset, int length) { final int netDestOffset = offset + destOffset; if (length >= SYSTEM_ARRAYCOPY_THRESHOLD) { // I wonder if this is wasteful because we already know the concrete type of src and data. System.arraycopy(src, srcOffset, data, netDestOffset, length); return; } if (ChunkHelpers.canCopyForward(src, srcOffset, data, destOffset, length)) { // noinspection ManualArrayCopy for (int ii = 0; ii < length; ++ii) { data[netDestOffset + ii] = src[srcOffset + ii]; } return; } // noinspection ManualArrayCopy for (int ii = length - 1; ii >= 0; --ii) { data[netDestOffset + ii] = src[srcOffset + ii]; } } // region CopyFromBuffer @Override public final void copyFromBuffer(@NotNull final Buffer srcBuffer, final int srcOffset, final int destOffset, final int length) { final CharBuffer charSrcBuffer = (CharBuffer) srcBuffer; copyFromTypedBuffer(charSrcBuffer, srcOffset, destOffset, length); } /** *

* Fill a sub-range of this WritableCharChunk with values from a {@link CharBuffer}. * *

* See {@link #copyFromBuffer(Buffer, int, int, int)} for general documentation. * * @param srcBuffer The source {@link CharBuffer} * @param srcOffset The absolute offset into {@code srcBuffer} to start copying from * @param destOffset The offset into this chunk to start copying to * @param length The number of elements to copy */ public final void copyFromTypedBuffer(@NotNull final CharBuffer srcBuffer, final int srcOffset, final int destOffset, final int length) { if (srcBuffer.hasArray()) { copyFromTypedArray(srcBuffer.array(), srcBuffer.arrayOffset() + srcOffset, destOffset, length); } else { final int initialPosition = srcBuffer.position(); srcBuffer.position(srcOffset); srcBuffer.get(data, offset + destOffset, length); srcBuffer.position(initialPosition); } } // endregion CopyFromBuffer @Override public final void sort() { sort(0, size); } // region sort @Override public final void sort(int start, int length) { Arrays.sort(data, offset + start, offset + start + length); // region SortFixup if (length <= 1) { return; } int foundLeft = Arrays.binarySearch(data, start, start + length, NULL_CHAR); if (foundLeft < 0) { return; } int foundRight = foundLeft; while (foundLeft > start && data[foundLeft - 1] == NULL_CHAR) { foundLeft--; } // If the nulls are already the leftmost thing, we are done. if (foundLeft > 0) { while (foundRight < start + length - 1 && data[foundRight + 1] == NULL_CHAR) { foundRight++; } final int nullCount = foundRight - foundLeft + 1; System.arraycopy(data, start, data, start + nullCount, foundLeft - start); Arrays.fill(data, start, start + nullCount, NULL_CHAR); } // endregion SortFixup } // endregion sort @Override public void close() {} // region downcast public static WritableCharChunk upcast( WritableCharChunk self) { // noinspection unchecked return (WritableCharChunk) self; } // endregion downcast }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy