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

com.hazelcast.config.FlakeIdGeneratorConfig Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.config;

import com.hazelcast.flakeidgen.FlakeIdGenerator;
import com.hazelcast.internal.config.ConfigDataSerializerHook;
import com.hazelcast.internal.monitor.LocalFlakeIdGeneratorStats;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.IdentifiedDataSerializable;

import java.io.IOException;
import java.util.Objects;

import static com.hazelcast.internal.util.Preconditions.checkNotNegative;
import static com.hazelcast.internal.util.Preconditions.checkTrue;

/**
 * The {@code FlakeIdGeneratorConfig} contains the configuration for the member
 * regarding {@link com.hazelcast.core.HazelcastInstance#getFlakeIdGenerator(String)
 * Flake ID Generator}.
 *
 * @since 3.10
 */
public class FlakeIdGeneratorConfig implements IdentifiedDataSerializable, NamedConfig {

    /**
     * Default value for {@link #getPrefetchCount()}.
     */
    public static final int DEFAULT_PREFETCH_COUNT = 100;

    /**
     * Default value for {@link #getPrefetchValidityMillis()}.
     */
    public static final long DEFAULT_PREFETCH_VALIDITY_MILLIS = 600000;

    /**
     * Default value for {@link #getEpochStart()}. {@code 1514764800000} is the value {@code
     * System.currentTimeMillis()} would return on 1.1.2018 0:00 UTC.
     */
    public static final long DEFAULT_EPOCH_START = 1514764800000L;

    /**
     * Default value for {@link #getBitsSequence()}.
     */
    public static final int DEFAULT_BITS_SEQUENCE = 6;

    /**
     * Default value for {@link #getBitsNodeId()}.
     */
    public static final int DEFAULT_BITS_NODE_ID = 16;

    /**
     * Default value for {@link #getAllowedFutureMillis()}.
     */
    public static final long DEFAULT_ALLOWED_FUTURE_MILLIS = 15000;

    /**
     * Maximum value for prefetch count. The limit is ~10% of the default time we allow the IDs to be from the future
     * (see {@link #DEFAULT_ALLOWED_FUTURE_MILLIS}).
     * 

* The reason to limit the prefetch count is that a single call to {@link FlakeIdGenerator#newId()} might * be blocked if the future allowance is exceeded: we want to avoid a single call for a large batch to block * another call for a small batch. */ public static final int MAXIMUM_PREFETCH_COUNT = 100000; private static final int MAX_BITS = 63; private String name; private int prefetchCount = DEFAULT_PREFETCH_COUNT; private long prefetchValidityMillis = DEFAULT_PREFETCH_VALIDITY_MILLIS; private long epochStart = DEFAULT_EPOCH_START; private long nodeIdOffset; private int bitsSequence = DEFAULT_BITS_SEQUENCE; private int bitsNodeId = DEFAULT_BITS_NODE_ID; private long allowedFutureMillis = DEFAULT_ALLOWED_FUTURE_MILLIS; private boolean statisticsEnabled = true; // for deserialization public FlakeIdGeneratorConfig() { } public FlakeIdGeneratorConfig(String name) { this.name = name; } /** * Copy-constructor */ public FlakeIdGeneratorConfig(FlakeIdGeneratorConfig other) { this.name = other.name; this.prefetchCount = other.prefetchCount; this.prefetchValidityMillis = other.prefetchValidityMillis; this.epochStart = other.epochStart; this.nodeIdOffset = other.nodeIdOffset; this.bitsSequence = other.bitsSequence; this.bitsNodeId = other.bitsNodeId; this.allowedFutureMillis = other.allowedFutureMillis; this.statisticsEnabled = other.statisticsEnabled; } /** * Returns the configuration name. This can be actual object name or pattern. */ public String getName() { return name; } /** * Sets the name or name pattern for this config. Must not be modified after this * instance is added to {@link Config}. */ public FlakeIdGeneratorConfig setName(String name) { this.name = name; return this; } /** * @see #setPrefetchCount(int) */ public int getPrefetchCount() { return prefetchCount; } /** * Sets how many IDs are pre-fetched on the background when one call to * {@link FlakeIdGenerator#newId()} is made. Default is 100. *

* This setting pertains only to {@link FlakeIdGenerator#newId newId()} calls made on the member * that configured it. * * @param prefetchCount the desired prefetch count, in the range 1..{@value #MAXIMUM_PREFETCH_COUNT}. * @return this instance for fluent API */ public FlakeIdGeneratorConfig setPrefetchCount(int prefetchCount) { checkTrue(prefetchCount > 0 && prefetchCount <= MAXIMUM_PREFETCH_COUNT, "prefetch-count must be 1.." + MAXIMUM_PREFETCH_COUNT + ", but is " + prefetchCount); this.prefetchCount = prefetchCount; return this; } /** * @see #setPrefetchValidityMillis(long) */ public long getPrefetchValidityMillis() { return prefetchValidityMillis; } /** * Sets for how long the pre-fetched IDs can be used. If this time elapses, a new batch of IDs will be * fetched. Time unit is milliseconds, default is 600,000 (10 minutes). *

* The IDs contain timestamp component, which ensures rough global ordering of IDs. If an ID * is assigned to an object that was created much later, it will be much out of order. If you don't care * about ordering, set this value to 0. *

* This setting pertains only to {@link FlakeIdGenerator#newId newId} calls made on the member * that configured it. * * @param prefetchValidityMs the desired ID validity or unlimited, if <=0 * @return this instance for fluent API */ public FlakeIdGeneratorConfig setPrefetchValidityMillis(long prefetchValidityMs) { this.prefetchValidityMillis = prefetchValidityMs; return this; } /** * Sets the offset of timestamp component in milliseconds. By default, it's {@value * DEFAULT_EPOCH_START}, that is the beginning of 2018. You can adjust the value to determine the * lifespan of the generator. See {@link FlakeIdGenerator}'s class javadoc for more information. *

* Note: If you set the epoch start to a future instant, negative IDs will be generated * until that time occurs. * * @param epochStart the desired epoch start * @return this instance for fluent API * @since 4.0 */ public FlakeIdGeneratorConfig setEpochStart(long epochStart) { this.epochStart = epochStart; return this; } /** * @see #setEpochStart(long) */ public long getEpochStart() { return epochStart; } /** * @see #setNodeIdOffset(long) */ public long getNodeIdOffset() { return nodeIdOffset; } /** * Sets the offset that will be added to the node ID assigned to cluster member for this generator. * Might be useful in A/B deployment scenarios where you have cluster A which you want to upgrade. * You create cluster B and for some time both will generate IDs and you want to have them unique. * In this case, configure node ID offset for generators on cluster B. * * @param nodeIdOffset the value added to the node id * @return this instance for fluent API * @see FlakeIdGenerator for the node id logic */ public FlakeIdGeneratorConfig setNodeIdOffset(long nodeIdOffset) { checkNotNegative(nodeIdOffset, "node id offset must be non-negative"); this.nodeIdOffset = nodeIdOffset; return this; } /** * @see #setBitsSequence(int) */ public int getBitsSequence() { return bitsSequence; } /** * Sets the bit-length of the sequence component. This setting determines the maximum rate at * which IDs can be generated. See {@link FlakeIdGenerator}'s class javadoc for more * information. * * @param bitsSequence sequence component bit-length * @return this instance for fluent API * @since 4.0 */ public FlakeIdGeneratorConfig setBitsSequence(int bitsSequence) { checkTrue(bitsSequence >= 0 && bitsSequence < MAX_BITS, "sequence bit-length must be 0.." + MAX_BITS); this.bitsSequence = bitsSequence; return this; } /** * @see #setBitsNodeId(int) */ public int getBitsNodeId() { return bitsNodeId; } /** * Sets the bit-length of node id component. See {@link FlakeIdGenerator}'s class javadoc for * more information. * * @param bitsNodeId node id component bit-length * @return this instance for fluent API * @since 4.0 */ public FlakeIdGeneratorConfig setBitsNodeId(int bitsNodeId) { checkTrue(bitsNodeId >= 0 && bitsNodeId < MAX_BITS, "node ID bit-length must be 0.." + MAX_BITS); this.bitsNodeId = bitsNodeId; return this; } /** * @see #setAllowedFutureMillis(long) */ public long getAllowedFutureMillis() { return allowedFutureMillis; } /** * Sets how far to the future is the generator allowed to go to generate IDs without blocking. *

* The number of bits configured for the sequence number ({@link #setBitsSequence(int)} * determines how many IDs can be generated per second. We allow the generator to generate IDs * with future timestamps, and this settings limits how much. When more IDs are requested, the * call will block. This is important in case of a cluster black-out or cluster restart: we * don't store how far the members went, and after they restart, they will start from current * time. If before the restart the generator went beyond the current time, duplicate IDs could * be generated. *

* The default value is 15 seconds (15000). If your cluster is able to restart more quickly, set * a lower value. *

* See {@link FlakeIdGenerator}'s class javadoc for more information. * * @param allowedFutureMillis value in milliseconds * @return this instance for fluent API * @since 4.0 */ public FlakeIdGeneratorConfig setAllowedFutureMillis(long allowedFutureMillis) { checkNotNegative(allowedFutureMillis, "allowedFutureMillis must be non-negative"); this.allowedFutureMillis = allowedFutureMillis; return this; } /** * @see #setStatisticsEnabled(boolean) */ public boolean isStatisticsEnabled() { return statisticsEnabled; } /** * Enables or disables statistics gathering of {@link LocalFlakeIdGeneratorStats}. * * @param statisticsEnabled {@code true} if statistics gathering is enabled * (which is also the default), {@code false} otherwise * @return this instance for fluent API */ public FlakeIdGeneratorConfig setStatisticsEnabled(boolean statisticsEnabled) { this.statisticsEnabled = statisticsEnabled; return this; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } FlakeIdGeneratorConfig that = (FlakeIdGeneratorConfig) o; return prefetchCount == that.prefetchCount && prefetchValidityMillis == that.prefetchValidityMillis && epochStart == that.epochStart && nodeIdOffset == that.nodeIdOffset && bitsSequence == that.bitsSequence && bitsNodeId == that.bitsNodeId && allowedFutureMillis == that.allowedFutureMillis && Objects.equals(name, that.name) && statisticsEnabled == that.statisticsEnabled; } @Override public int hashCode() { return Objects.hash( name, prefetchCount, prefetchValidityMillis, epochStart, nodeIdOffset, bitsSequence, bitsNodeId, allowedFutureMillis, statisticsEnabled); } @Override public String toString() { return "FlakeIdGeneratorConfig{" + "name='" + name + '\'' + ", prefetchCount=" + prefetchCount + ", prefetchValidityMillis=" + prefetchValidityMillis + ", epochStart=" + epochStart + ", nodeIdOffset=" + nodeIdOffset + ", bitsSequence=" + bitsSequence + ", bitsNodeId=" + bitsNodeId + ", allowedFutureMillis=" + allowedFutureMillis + ", statisticsEnabled=" + statisticsEnabled + '}'; } @Override public int getFactoryId() { return ConfigDataSerializerHook.F_ID; } @Override public int getClassId() { return ConfigDataSerializerHook.FLAKE_ID_GENERATOR_CONFIG; } @Override public void writeData(ObjectDataOutput out) throws IOException { out.writeString(name); out.writeInt(prefetchCount); out.writeLong(prefetchValidityMillis); out.writeLong(epochStart); out.writeLong(nodeIdOffset); out.writeInt(bitsSequence); out.writeInt(bitsNodeId); out.writeLong(allowedFutureMillis); out.writeBoolean(statisticsEnabled); } @Override public void readData(ObjectDataInput in) throws IOException { name = in.readString(); prefetchCount = in.readInt(); prefetchValidityMillis = in.readLong(); epochStart = in.readLong(); nodeIdOffset = in.readLong(); bitsSequence = in.readInt(); bitsNodeId = in.readInt(); allowedFutureMillis = in.readLong(); statisticsEnabled = in.readBoolean(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy