org.eclipse.jetty.util.AtomicBiInteger Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.util.concurrent.atomic.AtomicLong;
/**
* An AtomicLong with additional methods to treat it as two hi/lo integers.
*/
public class AtomicBiInteger extends AtomicLong
{
/**
* @return the hi value
*/
public int getHi()
{
return getHi(get());
}
/**
* @return the lo value
*/
public int getLo()
{
return getLo(get());
}
/**
* 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.
*
* @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.
*
* @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 {@code ==} the expected value.
* Concurrent changes to the lo value result in a retry.
*
* @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 {@code ==} the expected value.
* Concurrent changes to the hi value result in a retry.
*
* @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 {@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 {@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.
*
* @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.
*
* @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.
*
* @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;
}
}
/**
* 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);
}
/**
* 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);
}
/**
* 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.
*
* @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.
*
* @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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy