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

io.stargate.db.ImmutablePagingPosition Maven / Gradle / Ivy

There is a newer version: 2.1.0-BETA-19
Show newest version
package io.stargate.db;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.Var;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.stargate.db.schema.Column;
import io.stargate.db.schema.TableName;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
import org.immutables.value.Generated;

/**
 * Immutable implementation of {@link PagingPosition}.
 * 

* Use the builder to create immutable instances: * {@code ImmutablePagingPosition.builder()}. */ @Generated(from = "PagingPosition", generator = "Immutables") @SuppressWarnings({"all"}) @SuppressFBWarnings @ParametersAreNonnullByDefault @javax.annotation.Generated("org.immutables.processor.ProxyProcessor") @Immutable @CheckReturnValue public final class ImmutablePagingPosition implements PagingPosition { private final Map currentRow; private final PagingPosition.ResumeMode resumeFrom; private final int remainingRows; private final int remainingRowsInPartition; private ImmutablePagingPosition(ImmutablePagingPosition.Builder builder) { this.currentRow = createUnmodifiableMap(false, false, builder.currentRow); this.resumeFrom = builder.resumeFrom; if (builder.remainingRowsIsSet()) { initShim.remainingRows(builder.remainingRows); } if (builder.remainingRowsInPartitionIsSet()) { initShim.remainingRowsInPartition(builder.remainingRowsInPartition); } this.remainingRows = initShim.remainingRows(); this.remainingRowsInPartition = initShim.remainingRowsInPartition(); this.initShim = null; } private ImmutablePagingPosition( Map currentRow, PagingPosition.ResumeMode resumeFrom, int remainingRows, int remainingRowsInPartition) { this.currentRow = currentRow; this.resumeFrom = resumeFrom; this.remainingRows = remainingRows; this.remainingRowsInPartition = remainingRowsInPartition; this.initShim = null; } private static final byte STAGE_INITIALIZING = -1; private static final byte STAGE_UNINITIALIZED = 0; private static final byte STAGE_INITIALIZED = 1; @SuppressWarnings("Immutable") private transient volatile InitShim initShim = new InitShim(); @Generated(from = "PagingPosition", generator = "Immutables") private final class InitShim { private byte remainingRowsBuildStage = STAGE_UNINITIALIZED; private int remainingRows; int remainingRows() { if (remainingRowsBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); if (remainingRowsBuildStage == STAGE_UNINITIALIZED) { remainingRowsBuildStage = STAGE_INITIALIZING; this.remainingRows = remainingRowsInitialize(); remainingRowsBuildStage = STAGE_INITIALIZED; } return this.remainingRows; } void remainingRows(int remainingRows) { this.remainingRows = remainingRows; remainingRowsBuildStage = STAGE_INITIALIZED; } private byte remainingRowsInPartitionBuildStage = STAGE_UNINITIALIZED; private int remainingRowsInPartition; int remainingRowsInPartition() { if (remainingRowsInPartitionBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage()); if (remainingRowsInPartitionBuildStage == STAGE_UNINITIALIZED) { remainingRowsInPartitionBuildStage = STAGE_INITIALIZING; this.remainingRowsInPartition = remainingRowsInPartitionInitialize(); remainingRowsInPartitionBuildStage = STAGE_INITIALIZED; } return this.remainingRowsInPartition; } void remainingRowsInPartition(int remainingRowsInPartition) { this.remainingRowsInPartition = remainingRowsInPartition; remainingRowsInPartitionBuildStage = STAGE_INITIALIZED; } private String formatInitCycleMessage() { List attributes = new ArrayList<>(); if (remainingRowsBuildStage == STAGE_INITIALIZING) attributes.add("remainingRows"); if (remainingRowsInPartitionBuildStage == STAGE_INITIALIZING) attributes.add("remainingRowsInPartition"); return "Cannot build PagingPosition, attribute initializers form cycle " + attributes; } } private int remainingRowsInitialize() { return PagingPosition.super.remainingRows(); } private int remainingRowsInPartitionInitialize() { return PagingPosition.super.remainingRowsInPartition(); } /** *The reference row for the paging state. */ @Override public Map currentRow() { return currentRow; } /** *Defines how to resume paging relative to the {@link #currentRow() reference row}. */ @Override public PagingPosition.ResumeMode resumeFrom() { return resumeFrom; } /** * The maximum number of rows to be returned by the query execution requests using this paging * position. *

Note: since the custom paging position may be chosen arbitrarily, the caller is responsible * for tracking query limits and calculating the number of rows remaining. */ @Override public int remainingRows() { InitShim shim = this.initShim; return shim != null ? shim.remainingRows() : this.remainingRows; } /** * The maximum number of rows to be returned for next data partition in the query execution * requests using this paging position. *

Note: since the custom paging position may be chosen arbitrarily, the caller is responsible * for tracking per-partition query limits and calculating the number of rows remaining in next * partition. *

Note: if {@link ResumeMode#NEXT_PARTITION} is used, this parameter does not have to be set * (the per-partition limit will be inherited from the query). */ @Override public int remainingRowsInPartition() { InitShim shim = this.initShim; return shim != null ? shim.remainingRowsInPartition() : this.remainingRowsInPartition; } /** * Copy the current immutable object by replacing the {@link PagingPosition#currentRow() currentRow} map with the specified map. * Nulls are not permitted as keys or values. * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. * @param entries The entries to be added to the currentRow map * @return A modified copy of {@code this} object */ public final ImmutablePagingPosition withCurrentRow(Map entries) { if (this.currentRow == entries) return this; Map newValue = createUnmodifiableMap(true, false, entries); return new ImmutablePagingPosition(newValue, this.resumeFrom, this.remainingRows, this.remainingRowsInPartition); } /** * Copy the current immutable object by setting a value for the {@link PagingPosition#resumeFrom() resumeFrom} attribute. * A value equality check is used to prevent copying of the same value by returning {@code this}. * @param value A new value for resumeFrom * @return A modified copy of the {@code this} object */ public final ImmutablePagingPosition withResumeFrom(PagingPosition.ResumeMode value) { if (this.resumeFrom == value) return this; PagingPosition.ResumeMode newValue = Objects.requireNonNull(value, "resumeFrom"); if (this.resumeFrom.equals(newValue)) return this; return new ImmutablePagingPosition(this.currentRow, newValue, this.remainingRows, this.remainingRowsInPartition); } /** * Copy the current immutable object by setting a value for the {@link PagingPosition#remainingRows() remainingRows} attribute. * A value equality check is used to prevent copying of the same value by returning {@code this}. * @param value A new value for remainingRows * @return A modified copy of the {@code this} object */ public final ImmutablePagingPosition withRemainingRows(int value) { if (this.remainingRows == value) return this; return new ImmutablePagingPosition(this.currentRow, this.resumeFrom, value, this.remainingRowsInPartition); } /** * Copy the current immutable object by setting a value for the {@link PagingPosition#remainingRowsInPartition() remainingRowsInPartition} attribute. * A value equality check is used to prevent copying of the same value by returning {@code this}. * @param value A new value for remainingRowsInPartition * @return A modified copy of the {@code this} object */ public final ImmutablePagingPosition withRemainingRowsInPartition(int value) { if (this.remainingRowsInPartition == value) return this; return new ImmutablePagingPosition(this.currentRow, this.resumeFrom, this.remainingRows, value); } /** * This instance is equal to all instances of {@code ImmutablePagingPosition} that have equal attribute values. * @return {@code true} if {@code this} is equal to {@code another} instance */ @Override public boolean equals(@Nullable Object another) { if (this == another) return true; return another instanceof ImmutablePagingPosition && equalTo((ImmutablePagingPosition) another); } private boolean equalTo(ImmutablePagingPosition another) { return currentRow.equals(another.currentRow) && resumeFrom.equals(another.resumeFrom) && remainingRows == another.remainingRows && remainingRowsInPartition == another.remainingRowsInPartition; } /** * Computes a hash code from attributes: {@code currentRow}, {@code resumeFrom}, {@code remainingRows}, {@code remainingRowsInPartition}. * @return hashCode value */ @Override public int hashCode() { @Var int h = 5381; h += (h << 5) + currentRow.hashCode(); h += (h << 5) + resumeFrom.hashCode(); h += (h << 5) + remainingRows; h += (h << 5) + remainingRowsInPartition; return h; } /** * Prints the immutable value {@code PagingPosition} with attribute values. * @return A string representation of the value */ @Override public String toString() { return "PagingPosition{" + "currentRow=" + currentRow + ", resumeFrom=" + resumeFrom + ", remainingRows=" + remainingRows + ", remainingRowsInPartition=" + remainingRowsInPartition + "}"; } @SuppressWarnings("Immutable") private transient volatile long lazyInitBitmap; private static final long CURRENT_ROW_VALUES_BY_COLUMN_NAME_LAZY_INIT_BIT = 0x1L; @SuppressWarnings("Immutable") private transient Map currentRowValuesByColumnName; /** * {@inheritDoc} *

* Returns a lazily initialized value of the {@link PagingPosition#currentRowValuesByColumnName() currentRowValuesByColumnName} attribute. * Initialized once and only once and stored for subsequent access with proper synchronization. * In case of any exception or error thrown by the lazy value initializer, * the result will not be memoised (i.e. remembered) and on next call computation * will be attempted again. * @return A lazily initialized value of the {@code currentRowValuesByColumnName} attribute */ @Override public Map currentRowValuesByColumnName() { if ((lazyInitBitmap & CURRENT_ROW_VALUES_BY_COLUMN_NAME_LAZY_INIT_BIT) == 0) { synchronized (this) { if ((lazyInitBitmap & CURRENT_ROW_VALUES_BY_COLUMN_NAME_LAZY_INIT_BIT) == 0) { this.currentRowValuesByColumnName = Objects.requireNonNull(PagingPosition.super.currentRowValuesByColumnName(), "currentRowValuesByColumnName"); lazyInitBitmap |= CURRENT_ROW_VALUES_BY_COLUMN_NAME_LAZY_INIT_BIT; } } } return currentRowValuesByColumnName; } private static final long TABLE_NAME_LAZY_INIT_BIT = 0x2L; @SuppressWarnings("Immutable") private transient TableName tableName; /** * {@inheritDoc} *

* Returns a lazily initialized value of the {@link PagingPosition#tableName() tableName} attribute. * Initialized once and only once and stored for subsequent access with proper synchronization. * In case of any exception or error thrown by the lazy value initializer, * the result will not be memoised (i.e. remembered) and on next call computation * will be attempted again. * @return A lazily initialized value of the {@code tableName} attribute */ @Override public TableName tableName() { if ((lazyInitBitmap & TABLE_NAME_LAZY_INIT_BIT) == 0) { synchronized (this) { if ((lazyInitBitmap & TABLE_NAME_LAZY_INIT_BIT) == 0) { this.tableName = Objects.requireNonNull(PagingPosition.super.tableName(), "tableName"); lazyInitBitmap |= TABLE_NAME_LAZY_INIT_BIT; } } } return tableName; } /** * Creates an immutable copy of a {@link PagingPosition} value. * Uses accessors to get values to initialize the new immutable instance. * If an instance is already immutable, it is returned as is. * @param instance The instance to copy * @return A copied immutable PagingPosition instance */ public static ImmutablePagingPosition copyOf(PagingPosition instance) { if (instance instanceof ImmutablePagingPosition) { return (ImmutablePagingPosition) instance; } return ImmutablePagingPosition.builder() .from(instance) .build(); } /** * Creates a builder for {@link ImmutablePagingPosition ImmutablePagingPosition}. *

   * ImmutablePagingPosition.builder()
   *    .putCurrentRow|putAllCurrentRow(io.stargate.db.schema.Column => java.nio.ByteBuffer) // {@link PagingPosition#currentRow() currentRow} mappings
   *    .resumeFrom(io.stargate.db.PagingPosition.ResumeMode) // required {@link PagingPosition#resumeFrom() resumeFrom}
   *    .remainingRows(int) // optional {@link PagingPosition#remainingRows() remainingRows}
   *    .remainingRowsInPartition(int) // optional {@link PagingPosition#remainingRowsInPartition() remainingRowsInPartition}
   *    .build();
   * 
* @return A new ImmutablePagingPosition builder */ public static ImmutablePagingPosition.Builder builder() { return new ImmutablePagingPosition.Builder(); } /** * Builds instances of type {@link ImmutablePagingPosition ImmutablePagingPosition}. * Initialize attributes and then invoke the {@link #build()} method to create an * immutable instance. *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, * but instead used immediately to create instances. */ @Generated(from = "PagingPosition", generator = "Immutables") @NotThreadSafe public static final class Builder { private static final long INIT_BIT_RESUME_FROM = 0x1L; private static final long OPT_BIT_REMAINING_ROWS = 0x1L; private static final long OPT_BIT_REMAINING_ROWS_IN_PARTITION = 0x2L; private long initBits = 0x1L; private long optBits; private Map currentRow = new LinkedHashMap(); private @Nullable PagingPosition.ResumeMode resumeFrom; private int remainingRows; private int remainingRowsInPartition; private Builder() { } /** * Fill a builder with attribute values from the provided {@code PagingPosition} instance. * Regular attribute values will be replaced with those from the given instance. * Absent optional values will not replace present values. * Collection elements and entries will be added, not replaced. * @param instance The instance from which to copy values * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder from(PagingPosition instance) { Objects.requireNonNull(instance, "instance"); putAllCurrentRow(instance.currentRow()); resumeFrom(instance.resumeFrom()); remainingRows(instance.remainingRows()); remainingRowsInPartition(instance.remainingRowsInPartition()); return this; } /** * Put one entry to the {@link PagingPosition#currentRow() currentRow} map. * @param key The key in the currentRow map * @param value The associated value in the currentRow map * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder putCurrentRow(Column key, ByteBuffer value) { this.currentRow.put( Objects.requireNonNull(key, "currentRow key"), Objects.requireNonNull(value, "currentRow value")); return this; } /** * Put one entry to the {@link PagingPosition#currentRow() currentRow} map. Nulls are not permitted * @param entry The key and value entry * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder putCurrentRow(Map.Entry entry) { Column k = entry.getKey(); ByteBuffer v = entry.getValue(); this.currentRow.put( Objects.requireNonNull(k, "currentRow key"), Objects.requireNonNull(v, "currentRow value")); return this; } /** * Sets or replaces all mappings from the specified map as entries for the {@link PagingPosition#currentRow() currentRow} map. Nulls are not permitted * @param entries The entries that will be added to the currentRow map * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder currentRow(Map entries) { this.currentRow.clear(); return putAllCurrentRow(entries); } /** * Put all mappings from the specified map as entries to {@link PagingPosition#currentRow() currentRow} map. Nulls are not permitted * @param entries The entries that will be added to the currentRow map * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder putAllCurrentRow(Map entries) { for (Map.Entry e : entries.entrySet()) { Column k = e.getKey(); ByteBuffer v = e.getValue(); this.currentRow.put( Objects.requireNonNull(k, "currentRow key"), Objects.requireNonNull(v, "currentRow value")); } return this; } /** * Initializes the value for the {@link PagingPosition#resumeFrom() resumeFrom} attribute. * @param resumeFrom The value for resumeFrom * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder resumeFrom(PagingPosition.ResumeMode resumeFrom) { this.resumeFrom = Objects.requireNonNull(resumeFrom, "resumeFrom"); initBits &= ~INIT_BIT_RESUME_FROM; return this; } /** * Initializes the value for the {@link PagingPosition#remainingRows() remainingRows} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link PagingPosition#remainingRows() remainingRows}. * @param remainingRows The value for remainingRows * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder remainingRows(int remainingRows) { this.remainingRows = remainingRows; optBits |= OPT_BIT_REMAINING_ROWS; return this; } /** * Initializes the value for the {@link PagingPosition#remainingRowsInPartition() remainingRowsInPartition} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link PagingPosition#remainingRowsInPartition() remainingRowsInPartition}. * @param remainingRowsInPartition The value for remainingRowsInPartition * @return {@code this} builder for use in a chained invocation */ @CanIgnoreReturnValue public final Builder remainingRowsInPartition(int remainingRowsInPartition) { this.remainingRowsInPartition = remainingRowsInPartition; optBits |= OPT_BIT_REMAINING_ROWS_IN_PARTITION; return this; } /** * Builds a new {@link ImmutablePagingPosition ImmutablePagingPosition}. * @return An immutable instance of PagingPosition * @throws java.lang.IllegalStateException if any required attributes are missing */ public ImmutablePagingPosition build() { if (initBits != 0) { throw new IllegalStateException(formatRequiredAttributesMessage()); } return new ImmutablePagingPosition(this); } private boolean remainingRowsIsSet() { return (optBits & OPT_BIT_REMAINING_ROWS) != 0; } private boolean remainingRowsInPartitionIsSet() { return (optBits & OPT_BIT_REMAINING_ROWS_IN_PARTITION) != 0; } private String formatRequiredAttributesMessage() { List attributes = new ArrayList<>(); if ((initBits & INIT_BIT_RESUME_FROM) != 0) attributes.add("resumeFrom"); return "Cannot build PagingPosition, some of required attributes are not set " + attributes; } } private static Map createUnmodifiableMap(boolean checkNulls, boolean skipNulls, Map map) { switch (map.size()) { case 0: return Collections.emptyMap(); case 1: { Map.Entry e = map.entrySet().iterator().next(); K k = e.getKey(); V v = e.getValue(); if (checkNulls) { Objects.requireNonNull(k, "key"); Objects.requireNonNull(v, "value"); } if (skipNulls && (k == null || v == null)) { return Collections.emptyMap(); } return Collections.singletonMap(k, v); } default: { Map linkedMap = new LinkedHashMap<>(map.size()); if (skipNulls || checkNulls) { for (Map.Entry e : map.entrySet()) { K k = e.getKey(); V v = e.getValue(); if (skipNulls) { if (k == null || v == null) continue; } else if (checkNulls) { Objects.requireNonNull(k, "key"); Objects.requireNonNull(v, "value"); } linkedMap.put(k, v); } } else { linkedMap.putAll(map); } return Collections.unmodifiableMap(linkedMap); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy