/*
* Copyright 2017 Kjell Winblad (kjellwinblad@gmail.com, http://winsh.me).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* (see java/src/trees/lockbased/catreeutils/LICENSE)
*/
package trees.lockbased.catreeutils;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
* Objects of this class represents nodes in an AVL tree
* implementation. Please see "DualLFCASAVLTreeMapSTD.java" for
* details.
*
* @author Kjell Winblad
*/
public class STDAVLNodeDCAS<K,V>{
private static final AtomicReferenceFieldUpdater<STDAVLNodeDCAS, STDAVLNodeDCAS> leftUpdater =
AtomicReferenceFieldUpdater.newUpdater(STDAVLNodeDCAS.class, STDAVLNodeDCAS.class, "left");
private static final AtomicReferenceFieldUpdater<STDAVLNodeDCAS, STDAVLNodeDCAS> rightUpdater =
AtomicReferenceFieldUpdater.newUpdater(STDAVLNodeDCAS.class, STDAVLNodeDCAS.class, "right");
private static final AtomicReferenceFieldUpdater<STDAVLNodeDCAS, Object> valueUpdater =
AtomicReferenceFieldUpdater.newUpdater(STDAVLNodeDCAS.class, Object.class, "value");
K key;
private volatile STDAVLNodeDCAS<K,V> left;
private volatile STDAVLNodeDCAS<K,V> right;
private volatile Object value;
int balance = 0;
STDAVLNodeDCAS<K,V> parent = null;
public STDAVLNodeDCAS(K key, V value){
this.key = key;
this.value = (Object)value;
}
public STDAVLNodeDCAS<K,V> getLeft(){
return left;
}
public STDAVLNodeDCAS<K,V> getRight(){
return right;
}
public void setLeft(STDAVLNodeDCAS<K,V> n){
leftUpdater.lazySet(this, n);
}
public void setRight(STDAVLNodeDCAS<K,V> n){
rightUpdater.lazySet(this, n);
}
@SuppressWarnings("unchecked")
public V getValue(){
return (V)value;
}
public K getKey(){
return key;
}
public void setValue(V n){
valueUpdater.lazySet(this, (Object)n);
}
@SuppressWarnings("unchecked")
public V getAndSetValue(V n){
return (V)valueUpdater.getAndSet(this, (Object)n);
}
public boolean compareAndSet(V expect, V update){
return valueUpdater.compareAndSet(this, (Object)expect, (Object)update);
}
public String toString(){
return "NODE(" + key + ", " + balance + ")";
}
}
final class STDAVLNodeDCASNOFALSE<K,V> extends STDAVLNodeDCAS<K,V>{
AtomicReferenceArray<V> valueArray = new AtomicReferenceArray<V>(32);
public STDAVLNodeDCASNOFALSE(K key, V value){
super(key, value);
}
public V getValue(){
return (V)valueArray.get(16);
}
public void setValue(V n){
valueArray.lazySet(16, n);
}
public V getAndSetValue(V n){
return (V)valueArray.getAndSet(16, n);
}
public boolean compareAndSet(V expect, V update){
return valueArray.compareAndSet(16, expect, update);
}
public String toString(){
return "NODE(" + key + ", " + balance + ")";
}
}