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

io.deephaven.engine.table.impl.sources.regioned.RegionedColumnSourceArray Maven / Gradle / Ivy

There is a newer version: 0.37.1
Show newest version
/**
 * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
 */
package io.deephaven.engine.table.impl.sources.regioned;

import io.deephaven.base.verify.Require;

import javax.annotation.OverridingMethodsMustInvokeSuper;

import io.deephaven.chunk.attributes.Values;
import io.deephaven.engine.table.ColumnDefinition;
import io.deephaven.engine.table.impl.locations.ColumnLocation;
import io.deephaven.util.annotations.TestUseOnly;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.function.Supplier;

/**
 * Base class for all {@link RegionedColumnSource} implementations with column regions stored in an array.
 */
abstract class RegionedColumnSourceArray>
        extends RegionedColumnSourceBase
        implements MakeRegion {

    @FunctionalInterface
    interface MakeDeferred> {
        REGION_TYPE make(final long pageMask, Supplier supplier);
    }

    private final REGION_TYPE nullRegion;
    private final MakeDeferred makeDeferred;
    private volatile int regionCount = 0;
    private volatile REGION_TYPE[] regions;

    @SuppressWarnings("rawtypes")
    private static final ColumnRegion[] EMPTY = new ColumnRegion[0];

    private static > REGION_TYPE[] allocateRegionArray(
            int length) {
        // noinspection unchecked
        return (REGION_TYPE[]) (length == 0 ? EMPTY : new ColumnRegion[length]);
    }

    /**
     * Construct a {@code RegionedColumnSource} which is an array of references to {@code ColumnRegion}s.
     *
     * @param nullRegion A ColumnRegion to be used when the actual region doesn't exist, which returns the correct null
     *        values for that region.
     * @param type The type of the column.
     * @param componentType The component type in case the main type is a Vector
     * @param makeDeferred A function which creates the correct deferred region for this ColumnSource. If you don't want
     *        any deferred regions then use Supplier::get.
     */
    RegionedColumnSourceArray(@NotNull final REGION_TYPE nullRegion,
            @NotNull final Class type,
            @Nullable final Class componentType,
            @NotNull final MakeDeferred makeDeferred) {
        super(type, componentType);
        this.nullRegion = nullRegion;
        this.makeDeferred = makeDeferred;
        regions = allocateRegionArray(0);
    }

    /**
     * Delegate to {@link #RegionedColumnSourceArray(ColumnRegion, Class, Class, MakeDeferred)} with null component
     * type.
     *
     * @param nullRegion A ColumnRegion to be used when the actual region doesn't exist, which returns the correct null
     *        values for that region.
     * @param type The type of the column.
     * @param makeDeferred A function which creates the correct deferred region for this ColumnSource. If you don't want
     *        any deferred regions then use Supplier::get.
     */
    RegionedColumnSourceArray(@NotNull final REGION_TYPE nullRegion,
            @NotNull final Class type,
            @NotNull final MakeDeferred makeDeferred) {
        this(nullRegion, type, null, makeDeferred);
    }

    @Override
    @OverridingMethodsMustInvokeSuper
    public synchronized int addRegion(@NotNull final ColumnDefinition columnDefinition,
            @NotNull final ColumnLocation columnLocation) {
        maybeExtendRegions();
        final int regionIndex = regionCount;
        regions[regionIndex] = makeDeferred.make(PARAMETERS.regionMask,
                () -> updateRegion(regionIndex, makeRegion(columnDefinition, columnLocation, regionIndex)));
        return regionCount++;
    }

    /**
     * 

* Add a pre-constructed region without going through the abstract factory method * {@link #makeRegion(ColumnDefinition, ColumnLocation, int)}. *

* This method is for unit testing purposes only! * * @param region The region to add * @return The index assigned to the added region */ @Override @TestUseOnly synchronized int addRegionForUnitTests(final OTHER_REGION_TYPE region) { Require.neqNull(region, "region"); maybeExtendRegions(); // noinspection unchecked regions[regionCount] = region == null ? nullRegion : (REGION_TYPE) region; return regionCount++; } /** * Re-allocate the {@code regions} array if needed. */ private void maybeExtendRegions() { if (regionCount < regions.length) { return; } if (regionCount == MAXIMUM_REGION_COUNT) { throw new IllegalStateException("Cannot add another region to " + this + ", maximum region count " + MAXIMUM_REGION_COUNT + " reached"); } final int newLength = Math.min(Math.max(regions.length * 2, regionCount + 1), MAXIMUM_REGION_COUNT); final REGION_TYPE[] newRegions = allocateRegionArray(newLength); System.arraycopy(regions, 0, newRegions, 0, regionCount); regions = newRegions; } /** * Update the region at a given index in this regioned column source. This is intended to be used by the region * suppliers in DeferredColumnRegion implementations. * * @param regionIndex The region index * @param region The new column region * @return The new column region, for method-chaining purposes */ @NotNull private synchronized REGION_TYPE updateRegion(final int regionIndex, final REGION_TYPE region) { return regions[regionIndex] = region == null ? nullRegion : region; } @Override public final int getRegionCount() { return regionCount; } @Override public REGION_TYPE getRegion(final int regionIndex) { return regions[regionIndex]; } @Override @OverridingMethodsMustInvokeSuper public void releaseCachedResources() { super.releaseCachedResources(); for (int ri = 0; ri < getRegionCount(); ++ri) { getRegion(ri).releaseCachedResources(); } } @NotNull public final REGION_TYPE getNullRegion() { return nullRegion; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy