//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.util;

import java.util.concurrent.atomic.AtomicLong;

An AtomicLong with additional methods to treat it as two hi/lo integers.
/** * An AtomicLong with additional methods to treat it as two hi/lo integers. */
public class AtomicBiInteger extends AtomicLong { public AtomicBiInteger() { } public AtomicBiInteger(long encoded) { super(encoded); } public AtomicBiInteger(int hi, int lo) { super(encode(hi, lo)); }
Returns:the hi value
/** * @return the hi value */
public int getHi() { return getHi(get()); }
Gets a hi value from the given encoded value.
Params:
  • encoded – the encoded value
Returns:the hi value
/** * Gets a hi value from the given encoded value. * * @param encoded the encoded value * @return the hi value */
public static int getHi(long encoded) { return (int)((encoded >> 32) & 0xFFFF_FFFFL); }
Returns:the lo value
/** * @return the lo value */
public int getLo() { return getLo(get()); }
Gets a lo value from the given encoded value.
Params:
  • encoded – the encoded value
Returns:the lo value
/** * Gets a lo value from the given encoded value. * * @param encoded the encoded value * @return the lo value */
public static int getLo(long encoded) { return (int)(encoded & 0xFFFF_FFFFL); }
Atomically sets the hi value without changing the lo value.
Params:
  • hi – the new hi value
Returns:the previous hi value
/** * Atomically sets the hi value without changing the lo value. * * @param hi the new hi value * @return the previous hi value */
public int getAndSetHi(int hi) { while (true) { long encoded = get(); long update = encodeHi(encoded, hi); if (compareAndSet(encoded, update)) return getHi(encoded); } }
Atomically sets the lo value without changing the hi value.
Params:
  • lo – the new lo value
Returns:the previous lo value
/** * Atomically sets the lo value without changing the hi value. * * @param lo the new lo value * @return the previous lo value */
public int getAndSetLo(int lo) { while (true) { long encoded = get(); long update = encodeLo(encoded, lo); if (compareAndSet(encoded, update)) return getLo(encoded); } }
Sets the hi and lo values.
Params:
  • hi – the new hi value
  • lo – the new lo value
/** * Sets the hi and lo values. * * @param hi the new hi value * @param lo the new lo value */
public void set(int hi, int lo) { set(encode(hi, lo)); }

Atomically sets the hi value to the given updated value only if the current value == the expected value.

Concurrent changes to the lo value result in a retry.

Params:
  • expectHi – the expected hi value
  • hi – the new hi value
Returns:true if successful. False return indicates that the actual hi value was not equal to the expected hi value.
/** * <p>Atomically sets the hi value to the given updated value * only if the current value {@code ==} the expected value.</p> * <p>Concurrent changes to the lo value result in a retry.</p> * * @param expectHi the expected hi value * @param hi the new hi value * @return {@code true} if successful. False return indicates that * the actual hi value was not equal to the expected hi value. */
public boolean compareAndSetHi(int expectHi, int hi) { while (true) { long encoded = get(); if (getHi(encoded) != expectHi) return false; long update = encodeHi(encoded, hi); if (compareAndSet(encoded, update)) return true; } }

Atomically sets the lo value to the given updated value only if the current value == the expected value.

Concurrent changes to the hi value result in a retry.

Params:
  • expectLo – the expected lo value
  • lo – the new lo value
Returns:true if successful. False return indicates that the actual lo value was not equal to the expected lo value.
/** * <p>Atomically sets the lo value to the given updated value * only if the current value {@code ==} the expected value.</p> * <p>Concurrent changes to the hi value result in a retry.</p> * * @param expectLo the expected lo value * @param lo the new lo value * @return {@code true} if successful. False return indicates that * the actual lo value was not equal to the expected lo value. */
public boolean compareAndSetLo(int expectLo, int lo) { while (true) { long encoded = get(); if (getLo(encoded) != expectLo) return false; long update = encodeLo(encoded, lo); if (compareAndSet(encoded, update)) return true; } }
Atomically sets the values to the given updated values only if the current encoded value == the expected encoded value.
Params:
  • encoded – the expected encoded value
  • hi – the new hi value
  • lo – the new lo value
Returns:true if successful. False return indicates that the actual encoded value was not equal to the expected encoded value.
/** * Atomically sets the values to the given updated values only if * the current encoded value {@code ==} the expected encoded value. * * @param encoded the expected encoded value * @param hi the new hi value * @param lo the new lo value * @return {@code true} if successful. False return indicates that * the actual encoded value was not equal to the expected encoded value. */
public boolean compareAndSet(long encoded, int hi, int lo) { long update = encode(hi, lo); return compareAndSet(encoded, update); }
Atomically sets the hi and lo values to the given updated values only if the current hi and lo values == the expected hi and lo values.
Params:
  • expectHi – the expected hi value
  • hi – the new hi value
  • expectLo – the expected lo value
  • lo – the new lo value
Returns:true if successful. False return indicates that the actual hi and lo values were not equal to the expected hi and lo value.
/** * Atomically sets the hi and lo values to the given updated values only if * the current hi and lo values {@code ==} the expected hi and lo values. * * @param expectHi the expected hi value * @param hi the new hi value * @param expectLo the expected lo value * @param lo the new lo value * @return {@code true} if successful. False return indicates that * the actual hi and lo values were not equal to the expected hi and lo value. */
public boolean compareAndSet(int expectHi, int hi, int expectLo, int lo) { long encoded = encode(expectHi, expectLo); long update = encode(hi, lo); return compareAndSet(encoded, update); }
Atomically adds the given delta to the current hi value, returning the updated hi value.
Params:
  • delta – the delta to apply
Returns:the updated hi value
/** * Atomically adds the given delta to the current hi value, returning the updated hi value. * * @param delta the delta to apply * @return the updated hi value */
public int addAndGetHi(int delta) { while (true) { long encoded = get(); int hi = getHi(encoded) + delta; long update = encodeHi(encoded, hi); if (compareAndSet(encoded, update)) return hi; } }
Atomically adds the given delta to the current lo value, returning the updated lo value.
Params:
  • delta – the delta to apply
Returns:the updated lo value
/** * Atomically adds the given delta to the current lo value, returning the updated lo value. * * @param delta the delta to apply * @return the updated lo value */
public int addAndGetLo(int delta) { while (true) { long encoded = get(); int lo = getLo(encoded) + delta; long update = encodeLo(encoded, lo); if (compareAndSet(encoded, update)) return lo; } }
Atomically adds the given deltas to the current hi and lo values.
Params:
  • deltaHi – the delta to apply to the hi value
  • deltaLo – the delta to apply to the lo value
/** * Atomically adds the given deltas to the current hi and lo values. * * @param deltaHi the delta to apply to the hi value * @param deltaLo the delta to apply to the lo value */
public void add(int deltaHi, int deltaLo) { while (true) { long encoded = get(); long update = encode(getHi(encoded) + deltaHi, getLo(encoded) + deltaLo); if (compareAndSet(encoded, update)) return; } }
Encodes hi and lo values into a long.
Params:
  • hi – the hi value
  • lo – the lo value
Returns:the encoded value
/** * Encodes hi and lo values into a long. * * @param hi the hi value * @param lo the lo value * @return the encoded value */
public static long encode(int hi, int lo) { long h = ((long)hi) & 0xFFFF_FFFFL; long l = ((long)lo) & 0xFFFF_FFFFL; return (h << 32) + l; }
Sets the hi value into the given encoded value.
Params:
  • encoded – the encoded value
  • hi – the hi value
Returns:the new encoded value
/** * Sets the hi value into the given encoded value. * * @param encoded the encoded value * @param hi the hi value * @return the new encoded value */
public static long encodeHi(long encoded, int hi) { long h = ((long)hi) & 0xFFFF_FFFFL; long l = encoded & 0xFFFF_FFFFL; return (h << 32) + l; }
Sets the lo value into the given encoded value.
Params:
  • encoded – the encoded value
  • lo – the lo value
Returns:the new encoded value
/** * Sets the lo value into the given encoded value. * * @param encoded the encoded value * @param lo the lo value * @return the new encoded value */
public static long encodeLo(long encoded, int lo) { long h = (encoded >> 32) & 0xFFFF_FFFFL; long l = ((long)lo) & 0xFFFF_FFFFL; return (h << 32) + l; } }