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

com.swirlds.metrics.impl.AtomicDouble Maven / Gradle / Ivy

Go to download

Swirlds is a software platform designed to build fully-distributed applications that harness the power of the cloud without servers. Now you can develop applications with fairness in decision making, speed, trust and reliability, at a fraction of the cost of traditional server-based platforms.

There is a newer version: 0.56.6
Show newest version
/*
 * Copyright (C) 2024 Hedera Hashgraph, LLC
 *
 * 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.swirlds.metrics.impl;

import static java.lang.Double.doubleToRawLongBits;
import static java.lang.Double.longBitsToDouble;

import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleUnaryOperator;

/**
 * A (partial) implementation of an {@code AtomicDouble}, which allows atomic updates and
 * CAS-operations on a {@code double} value.
 * 

* This implementation is inspired by the {@code AtomicDouble} implementations in JSR 166 extra and Guava. *

* Note: In CAS-operations, this class does not compare the {@code double}-values directly, but the * bits one gets by calling {@link Double#doubleToRawLongBits(double)}. */ public class AtomicDouble { private volatile long bits; private static final AtomicLongFieldUpdater updater = AtomicLongFieldUpdater.newUpdater(AtomicDouble.class, "bits"); /** * Creates a new {@code AtomicLong} with the given initial value. * * @param initialValue * the initial value */ public AtomicDouble(double initialValue) { bits = doubleToRawLongBits(initialValue); } /** * Creates a new {@code AtomicDouble} with initial value {@code 0.0}. */ public AtomicDouble() {} /** * Returns the current value, with memory effects as specified by * {@link java.lang.invoke.VarHandle#getVolatile(Object...)}. * * @return the current value */ public final double get() { return longBitsToDouble(bits); } /** * Sets the value to newValue, with memory effects as specified by * {@link java.lang.invoke.VarHandle#setVolatile(Object...)}. * * @param newValue * the new value */ public final void set(double newValue) { bits = doubleToRawLongBits(newValue); } /** * Atomically sets the value to {@code newValue} and returns the old value. * * @param newValue * the new value * @return the previous value */ public final double getAndSet(double newValue) { final long newBits = doubleToRawLongBits(newValue); return longBitsToDouble(updater.getAndSet(this, newBits)); } /** * Atomically sets the value to the given updated value if the current value is bitwise equal, that is, * if {@link Double#doubleToRawLongBits(double)} returns the same value. * * @param expectedValue * the expected value * @param newValue * the new value * @return {@code true} if successful, {@code false} otherwise. */ public final boolean compareAndSet(double expectedValue, double newValue) { final long expectedBits = doubleToRawLongBits(expectedValue); final long newBits = doubleToRawLongBits(newValue); return updater.compareAndSet(this, expectedBits, newBits); } /** * Atomically adds the given value to the current value. * * @param delta the value to add * @return the updated value */ public final double addAndGet(final double delta) { return accumulateAndGet(delta, Double::sum); } /** * Atomically updates the current value with the results of applying the given function to the * current and given values. * * @param updateValue the update value * @param accumulatorFunction the accumulator function * @return the updated value */ public final double accumulateAndGet( final double updateValue, @NonNull final DoubleBinaryOperator accumulatorFunction) { Objects.requireNonNull(accumulatorFunction); return updateAndGet(oldValue -> accumulatorFunction.applyAsDouble(oldValue, updateValue)); } /** * Atomically updates the current value with the results of applying the given function. * * @param updateFunction the update function * @return the updated value */ public final double updateAndGet(@NonNull final DoubleUnaryOperator updateFunction) { Objects.requireNonNull(updateFunction); while (true) { long current = bits; double currentVal = longBitsToDouble(current); double nextVal = updateFunction.applyAsDouble(currentVal); long next = doubleToRawLongBits(nextVal); if (updater.compareAndSet(this, current, next)) { return nextVal; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy