hazelcast-master/hazelcast/src/main/java/com/hazelcast/internal/partition/PartitionStampUtil.java
/*
 * Copyright (c) 2008-2023, 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.internal.partition;

import com.hazelcast.internal.nio.Bits;
import com.hazelcast.internal.util.HashUtil;

import javax.annotation.Nonnull;
import java.util.function.Supplier;

/**
 * PartitionStampUtil is a utility class to generate stamp for the partition table.
 */
public final class PartitionStampUtil {

    private PartitionStampUtil() {
    }

    /**
     * Calculates 64-bit stamp value for the given partitions.
     * Stamp is calculated by hashing the individual partition versions
     * using MurmurHash3.
     *
     * @param partitions partition table
     * @return stamp value
     */
    public static long calculateStamp(@Nonnull InternalPartition[] partitions) {
        return calculateStamp(partitions, () -> new byte[Integer.BYTES * partitions.length]);
    }


    /**
     * Calculates 64-bit stamp value for the given partitions.
     * Stamp is calculated by hashing the individual partition versions
     * using MurmurHash3.
     *
     * @param partitions     partition table
     * @param bufferSupplier supplier for the buffer to use when calculating the stamp. The buffer
     *                       returned from this supplier should have a size equal to
     *                       {@code partitions.length} ints.
     * @return stamp value
     */
    public static long calculateStamp(@Nonnull InternalPartition[] partitions,
                                      @Nonnull Supplier<byte[]> bufferSupplier) {
        byte[] bb = bufferSupplier.get();
        assert bb.length == Integer.BYTES * partitions.length
                : "The supplied buffer should have a size of partitions.length bytes";

        for (InternalPartition partition : partitions) {
            Bits.writeIntB(bb, partition.getPartitionId() * Integer.BYTES, partition.version());
        }
        return HashUtil.MurmurHash3_x64_64(bb, 0, bb.length);
    }
}
