view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/util/Commitment.java @ 29:53090dc21231

added Commitment
author Shoshi TAMAKI
date Tue, 15 Jan 2013 02:24:42 +0900
parents
children
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.util;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Pair;

public final class Commitment
{
	private Commitment()
	{
		// 
	}
	
	public static <T> Pair<Publisher<T>,Value<T>> newInstance(T _draft,T _sub)
	{
		ValueWrapper<T> fail = new ValueWrapper<T>(_sub);
		ValueWrapper<T> init = new ValueWrapper<T>(_sub);
		ValueWrapper<T> draft = new ValueWrapper<T>(_draft);
		AtomicReference<ValueWrapper<T>> value = new AtomicReference<ValueWrapper<T>>(init);
		
		Publisher<T> p = new Publisher<T>(value,draft,fail);
		Value<T> v = new Value<T>(value,fail);
		
		return new Pair<Publisher<T>,Value<T>>(p,v);
	}
	
	public static class Publisher<T>
	{
		private final AtomicReference<ValueWrapper<T>> value;
		private final ValueWrapper<T> draft;
		private final AtomicBoolean flag;
		private final ValueWrapper<T> fail;
		
		Publisher(AtomicReference<ValueWrapper<T>> _value,ValueWrapper<T> _draft,ValueWrapper<T> _fail)
		{
			value = _value;
			draft = _draft;
			flag = new AtomicBoolean(false);
			fail = _fail;
		}
		
		public void commit()
		{
			if(flag.compareAndSet(true,false)){
				value.set(draft);
			}
		}
		
		public void fail()
		{
			if(flag.compareAndSet(true,false)){
				value.set(fail);
			}
		}
	}
	
	public static class Value<T>
	{
		private final AtomicReference<ValueWrapper<T>> value;
		private final ValueWrapper<T> fail;
		
		Value(AtomicReference<ValueWrapper<T>> _value,ValueWrapper<T> _fail)
		{
			value = _value;
			fail = _fail;
		}
		
		public T get()
		{
			return value.get().get();
		}
		
		public boolean isFail()
		{
			return (value.get() == fail);
		}
	}
	
	private static class ValueWrapper<T>
	{
		private final T object;
		
		public ValueWrapper(T _object)
		{
			object = _object;
		}
		
		public T get()
		{
			return object;
		}
	}
}