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

io.deephaven.chunk.util.pools.ObjectChunkSoftPool Maven / Gradle / Ivy

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

import io.deephaven.util.type.ArrayTypeUtils;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.*;
import io.deephaven.util.datastructures.SegmentedSoftPool;
import org.jetbrains.annotations.NotNull;

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

/**
 * {@link ChunkPool} implementation for chunks of objects.
 */
@SuppressWarnings("rawtypes")
public final class ObjectChunkSoftPool implements ChunkPool, ObjectChunkPool {

    private final WritableObjectChunk EMPTY =
            WritableObjectChunk.writableChunkWrap(ArrayTypeUtils.EMPTY_OBJECT_ARRAY);

    /**
     * Sub-pools by power-of-two sizes for {@link WritableObjectChunk}s.
     */
    private final SegmentedSoftPool[] writableObjectChunks;

    /**
     * Sub-pool of {@link ResettableObjectChunk}s.
     */
    private final SegmentedSoftPool resettableObjectChunks;

    /**
     * Sub-pool of {@link ResettableWritableObjectChunk}s.
     */
    private final SegmentedSoftPool resettableWritableObjectChunks;

    ObjectChunkSoftPool() {
        // noinspection unchecked
        writableObjectChunks =
                (SegmentedSoftPool[]) new SegmentedSoftPool[NUM_POOLED_CHUNK_CAPACITIES];
        for (int pcci = 0; pcci < NUM_POOLED_CHUNK_CAPACITIES; ++pcci) {
            final int chunkLog2Capacity = pcci + SMALLEST_POOLED_CHUNK_LOG2_CAPACITY;
            final int chunkCapacity = 1 << chunkLog2Capacity;
            writableObjectChunks[pcci] = new SegmentedSoftPool<>(
                    SUB_POOL_SEGMENT_CAPACITY,
                    () -> ChunkPoolInstrumentation
                            .getAndRecord(() -> WritableObjectChunk.makeWritableChunkForPool(chunkCapacity)),
                    (final WritableObjectChunk chunk) -> {
                        chunk.fillWithNullValue(0, chunkCapacity);
                        chunk.setSize(chunkCapacity);
                    });
        }
        resettableObjectChunks = new SegmentedSoftPool<>(
                SUB_POOL_SEGMENT_CAPACITY,
                () -> ChunkPoolInstrumentation.getAndRecord(ResettableObjectChunk::makeResettableChunkForPool),
                ResettableObjectChunk::clear);
        resettableWritableObjectChunks = new SegmentedSoftPool<>(
                SUB_POOL_SEGMENT_CAPACITY,
                () -> ChunkPoolInstrumentation.getAndRecord(ResettableWritableObjectChunk::makeResettableChunkForPool),
                ResettableWritableObjectChunk::clear);
    }

    @Override
    public ChunkPool asChunkPool() {
        return new ChunkPool() {
            @Override
            public  WritableChunk takeWritableChunk(final int capacity) {
                return takeWritableObjectChunk(capacity);
            }

            @Override
            public  void giveWritableChunk(@NotNull final WritableChunk writableChunk) {
                giveWritableObjectChunk(writableChunk.asWritableObjectChunk());
            }

            @Override
            public  ResettableReadOnlyChunk takeResettableChunk() {
                return takeResettableObjectChunk();
            }

            @Override
            public  void giveResettableChunk(
                    @NotNull final ResettableReadOnlyChunk resettableChunk) {
                giveResettableObjectChunk(resettableChunk.asResettableObjectChunk());
            }

            @Override
            public  ResettableWritableChunk takeResettableWritableChunk() {
                return takeResettableWritableObjectChunk();
            }

            @Override
            public  void giveResettableWritableChunk(
                    @NotNull final ResettableWritableChunk resettableWritableChunk) {
                giveResettableWritableObjectChunk(resettableWritableChunk.asResettableWritableObjectChunk());
            }
        };
    }

    @Override
    public  WritableChunk takeWritableChunk(final int capacity) {
        return takeWritableObjectChunk(capacity);
    }

    @Override
    public  void giveWritableChunk(@NotNull final WritableChunk writableChunk) {
        giveWritableObjectChunk(writableChunk.asWritableObjectChunk());
    }

    @Override
    public  ResettableReadOnlyChunk takeResettableChunk() {
        return takeResettableObjectChunk();
    }

    @Override
    public  void giveResettableChunk(@NotNull final ResettableReadOnlyChunk resettableChunk) {
        giveResettableObjectChunk(resettableChunk.asResettableObjectChunk());
    }

    @Override
    public  ResettableWritableChunk takeResettableWritableChunk() {
        return takeResettableWritableObjectChunk();
    }

    @Override
    public  void giveResettableWritableChunk(
            @NotNull final ResettableWritableChunk resettableWritableChunk) {
        giveResettableWritableObjectChunk(resettableWritableChunk.asResettableWritableObjectChunk());
    }

    @Override
    public  WritableObjectChunk takeWritableObjectChunk(final int capacity) {
        if (capacity == 0) {
            // noinspection unchecked
            return (WritableObjectChunk) EMPTY;
        }
        final int poolIndexForTake = getPoolIndexForTake(checkCapacityBounds(capacity));
        if (poolIndexForTake >= 0) {
            // noinspection resource
            final WritableObjectChunk result = writableObjectChunks[poolIndexForTake].take();
            result.setSize(capacity);
            // noinspection unchecked
            return ChunkPoolReleaseTracking.onTake(result);
        }
        // noinspection unchecked
        return ChunkPoolReleaseTracking.onTake(WritableObjectChunk.makeWritableChunkForPool(capacity));
    }

    @Override
    public void giveWritableObjectChunk(@NotNull final WritableObjectChunk writableObjectChunk) {
        if (writableObjectChunk == EMPTY || writableObjectChunk.isAlias(EMPTY)) {
            return;
        }
        ChunkPoolReleaseTracking.onGive(writableObjectChunk);
        final int capacity = writableObjectChunk.capacity();
        final int poolIndexForGive = getPoolIndexForGive(checkCapacityBounds(capacity));
        if (poolIndexForGive >= 0) {
            writableObjectChunks[poolIndexForGive].give(writableObjectChunk);
        }
    }

    @Override
    public  ResettableObjectChunk takeResettableObjectChunk() {
        // noinspection unchecked
        return ChunkPoolReleaseTracking.onTake(resettableObjectChunks.take());
    }

    @Override
    public void giveResettableObjectChunk(@NotNull final ResettableObjectChunk resettableObjectChunk) {
        resettableObjectChunks.give(ChunkPoolReleaseTracking.onGive(resettableObjectChunk));
    }

    @Override
    public  ResettableWritableObjectChunk takeResettableWritableObjectChunk() {
        // noinspection unchecked
        return ChunkPoolReleaseTracking.onTake(resettableWritableObjectChunks.take());
    }

    @Override
    public void giveResettableWritableObjectChunk(
            @NotNull final ResettableWritableObjectChunk resettableWritableObjectChunk) {
        resettableWritableObjectChunks.give(ChunkPoolReleaseTracking.onGive(resettableWritableObjectChunk));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy